// IA32Interpreter.cpp
// Implement the class IA32Interpreter

#include "crossbit/common.h"
#include "crossbit/VInst.h"
#include "crossbit/ELFMemoryImage.h"
#include "arch/ia32/IA32VBasicBlockBuilder.h"
#include "arch/ia32/IA32Interpreter.h"
#include "arch/ia32/IA32Syscall.h"
#include <iostream>
#include <cmath>
#include "disasm.h"

namespace crossbit{
#define t1 41
#define t2 42
#define t3 43
#define t4 44
#define t5 45

#define VREG(a)    ((a) + 1)

#define NEAX 0

#define SR  8

#define NCF 15
#define NOF 16
#define NSF 17
#define NZF 18
#define NAF 19
#define NPF 20

#define	SEG_BASE    26

// Reserved Vregs for VFilters, added by zyc
#define FILTER_REG1		27
#define FILTER_REG2		28

#define MODRMREG 29
#define TEMPREG0 30
#define TEMPREG1 31
#define TEMPREG2 32
#define TEMPREG3 33
#define TEMPREG4 34
#define TEMPREG5 35
#define TEMPREG6 36
#define TEMPREG7 37
#define TEMPREG8 38
#define TEMPREG9 39

    static BlockSize op_size = WORD;
    static DataType dtype = s32;

    // G-VInst
#define IA32GET(a,b)	GET((a),(b),dtype)
#define IA32PUT(a,b)	PUT((a),(b),dtype)
#define IA32MOV(a,b)    MOV((a),(b),s32)
#define IA32LI(a,b)     LI((a),(b),s32)
#define IA32ADD(a,b,c)  ADD((a),(b),(c),s32)
#define IA32ADDI(a,b,c) ADDI((a),(b),(c),s32)
#define IA32SUB(a,b,c)  SUB((a),(b),(c),s32)
#define IA32SUBI(a,b,c) SUBI((a),(b),(c),s32)
#define IA32AND(a,b,c)  AND((a),(b),(c),s32)
#define IA32XOR(a,b,c)  XOR((a),(b),(c),s32)
#define IA32OR(a,b,c)   OR((a),(b),(c),s32)
#define IA32NOT(a,b)    NOT((a),(b),s32)
#define IA32SLL(a,b,c)  SLL((a),(b),(c),s32)
#define IA32SRL(a,b,c)  SRL((a),(b),(c),s32)
#define IA32SRA(a,b,c)  SRA((a),(b),(c),s32)
#define IA32MUL(a,b,c,d)    MUL((a),(b),-1,(c),(d),s32)
#define IA32MULU(a,b,c,d)   MUL((a),(b),-1,(c),(d),u32)
#define IA32DIV(a,b,c,d)    DIV((a),(b),-1,(c),(d),s32)
#define DIVU64(a,b,c,d,e)   DIV((a),(b),(c),(d),(e),u64)
#define FCONV(a,b,c,d)  CONV((a),(b),(c),(d))
#define FGETD(a)        GET((a), (a), f64)
#define FPUTD(a)        PUT((a), (a), f64)


#define ibb ((IA32VBasicBlockBuilder *)bb)

    IA32Syscall* syscall;

    //add by chuchao
    volatile int hasRep = false;
    volatile int segOver = false;
    volatile XTRegNum segReg;

    volatile int repFlag = 0;
    volatile int eraseRep = 0;
    volatile unsigned int top = 0;

    volatile int curNext = 0;

    /**
     * It will be only used in the set flags function to improve performance.
     */
    Word* _regs = 0;

//#define ptx_msg true
#define ptx_msg (mode_ == PTX && false)
#define hyn_msg (mode_ == PTX && false)

    void set_seg_base(ProcessorState *state,int gs)
    {
        // empty now
    }

    void cmpxchg(ProcessorState *state,int reg, int rorm)
    {
        int r = state->reg(reg);
        int a = state->reg(NEAX);
        int b;
        if( rorm < 100 ) // NEED TODO
            b = state->reg(rorm);
        else
            b = *(int*)(rorm);

        if( a == b )
        {
            state->put(NZF, 1);
            //r[NZF]=1;
            *(int*)rorm = r;
        }
        else
        {
            state->put(NZF,0);
            state->put(NEAX, b);
        }
    }

    void syscallWrapper()
    {
        syscall->operator()();
    }

    void initializeSyscall(IA32Syscall* s)
    {
        syscall = s;
    }

// added by zhangyichao, 2010-4-15
#define SET_FLAGS_ADCL(a,b,c)	\
	ibb->add( IA32ADD((a), (b), TEMPREG4) );	\
	ibb->add( IA32ADD(TEMPREG4, (c), TEMPREG4) );	\
	ibb->add( CMP(EQ, (c), 0, TEMPREG5) );	\
	ibb->add( CMP(BE, TEMPREG4, (a), TEMPREG6) );	\
	ibb->add( IA32AND(TEMPREG5, TEMPREG6, NCF) );	\
	ibb->add( CMP(AB, TEMPREG4, (a), TEMPREG6) );	\
	ibb->add( IA32OR(TEMPREG5, TEMPREG6, TEMPREG6) );	\
	ibb->add( IA32NOT(TEMPREG6, NCF) );	\
	ibb->add( PUT(NCF, NCF, s32) );	\
	ibb->add( CMP(EQ, TEMPREG4, 0, NZF) );	\
	ibb->add( PUT(NZF, NZF, s32) );	\
	ibb->add( CMP(LT, TEMPREG4, 0, NSF) );	\
	ibb->add( PUT(NSF, NSF, s32) );	\
	ibb->add( CMP(LT, (a), 0, TEMPREG6) );	\
	ibb->add( CMP(LT, (b), 0, TEMPREG7) );	\
	ibb->add( IA32AND(TEMPREG6, TEMPREG7, TEMPREG9) );	\
	ibb->add( CMP(GE, TEMPREG4, 0, TEMPREG8) );	\
	ibb->add( IA32AND(TEMPREG8, TEMPREG6, TEMPREG8) );	\
	ibb->add( IA32AND(TEMPREG8, TEMPREG9, TEMPREG0) );	\
	ibb->add( IA32AND(TEMPREG5, TEMPREG0, NOF) );	\
	ibb->add( IA32NOT(TEMPREG5, TEMPREG5) );	\
	ibb->add( IA32ADD((a), (b), TEMPREG4) );	\
	ibb->add( CMP(GE, TEMPREG4, 0, TEMPREG8) );	\
	ibb->add( IA32AND(TEMPREG8, TEMPREG6, TEMPREG6) );	\
	ibb->add( IA32AND(TEMPREG9, TEMPREG6, TEMPREG6) );	\
	ibb->add( IA32AND(TEMPREG5, TEMPREG6, NOF) );	\
	ibb->add( IA32NOT(TEMPREG6, TEMPREG6) );	\
	ibb->add( IA32ADD(TEMPREG4, (c), TEMPREG0) );	\
	ibb->add( CMP(GT, TEMPREG4, 0, TEMPREG8) );	\
	ibb->add( CMP(GT, TEMPREG0, 0, TEMPREG9) );	\
	ibb->add( IA32AND(TEMPREG8, TEMPREG9, TEMPREG9) );	\
	ibb->add( IA32AND(TEMPREG6, TEMPREG9, NOF) );	\
	ibb->add( PUT(NOF, NOF, s32) );

    void set_flags_adcl(int a, int b, int c)
    {
        int tmp = a + b + c;

        if (c == 0)
        {
            if ( (unsigned)tmp < (unsigned)a )
            {
                _regs[NCF]=1;
            }
            else
            {
                _regs[NCF] = 0;
            }
        }
        else
        {
            if ( (unsigned)tmp <= (unsigned)a )
            {
                _regs[NCF]=1;
            }
            else
            {
                _regs[NCF] = 0;
            }
        }

        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ( (signed)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ( c == 0)
        {
            if ( ((a < 0) == (b < 0)) && ((tmp < 0) != (a < 0) ))
            {
                _regs[NOF]=1;
            }
            else
            {
                _regs[NOF] = 0;
            }
        }
        else
        {
            int d = a + b;

            if ( ((a < 0) == (b < 0)) && ((d < 0) != (a < 0) ))
            {
                _regs[NOF]=1;
            }
            else
            {
                int f = d + c;
                if ( d > 0 && f < 0 )
                    _regs[NOF] = 1;
                else
                    _regs[NOF] = 0;
            }
        }
        //TODO:set AF,PF according to the result
    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_ADDL(a, b)	\
	ibb->add( IA32ADD( (a), (b), TEMPREG3 ) );	\
	ibb->add( CMP( BE, TEMPREG3, (a), NCF ) );	\
	ibb->add( PUT( NCF, NCF, s32 ) );	\
	ibb->add( CMP( EQ, TEMPREG3, 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( CMP( LT, TEMPREG3, 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );	\
	ibb->add( CMP( LT, (a), 0, TEMPREG4 ) );	\
	ibb->add( CMP( LT, (b), 0, TEMPREG5 ) );	\
	ibb->add( CMP( EQ, TEMPREG4, TEMPREG5, TEMPREG5 ) );	\
	ibb->add( CMP( NE, NSF, TEMPREG4, TEMPREG4 ) );	\
	ibb->add( IA32AND( TEMPREG4, TEMPREG5, NOF ) );	\
	ibb->add( PUT( NOF, NOF, s32 ) );

    void set_flags_addl(int a, int b)
    {
        int tmp = a + b;
        if ( (unsigned)tmp < (unsigned)a )
        {
            _regs[NCF]=1;
        }
        else
        {
            _regs[NCF] = 0;
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ( (signed)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        if ( ((a < 0) == (b < 0)) && ((tmp < 0) != (a < 0) ))
        {
            _regs[NOF]=1;
        }
        else
        {
            _regs[NOF] = 0;
        }
        //TODO:set AF,PF according to the result
    }

    void set_flags_addw(int a,int b)
    {
        short c = (short)( a & 0xffff);
        short d = (short)( b & 0xffff);
        short tmp = c + d;
        if ( (unsigned short)tmp < (unsigned short)c )
        {
            _regs[NCF]=1;
        }
        else
        {
            _regs[NCF] = 0;
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ( tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        if ( (c < 0 == d < 0) && (tmp < 0 != c < 0 ))
        {
            _regs[NOF]=1;
        }
        else
        {
            _regs[NOF] = 0;
        }
        //TODO:set AF,PF according to the result
    }

    void set_flags_addb(int a, int b)
    {
        a = a & 0xff;
        b = b & 0xff;
        int tmp = a + b;
        tmp = tmp & 0xff;

        if ( (unsigned)tmp < (unsigned)a )
        {
            _regs[NCF]=1;
        }
        else
        {
            _regs[NCF] = 0;
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((tmp&0x80) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        if ( ((a&0x80 != 0) == (b&0x80 != 0)) && ((tmp &0x80!=0) != (a&0x80 !=0)))
        {
            _regs[NOF]=1;
        }
        else
        {
            _regs[NOF] = 0;
        }
        //TODO:set AF,PF according to the result
    }

	//added by zhangyichao, 2010-4-14
#define SET_FLAGS_SUBL(a,b)	\
		ibb->add (IA32SUB((a), (b), TEMPREG3));	\
		ibb->add (CMP(BE, (a), (b), NCF));	\
		ibb->add (CMP(LT, TEMPREG3, 0, NSF));	\
		ibb->add (CMP(EQ, TEMPREG3, 0, NZF));	\
		ibb->add (IA32PUT(NCF, NCF));	\
		ibb->add (IA32PUT(NSF, NSF));	\
		ibb->add (IA32PUT(NZF, NZF));	\
		ibb->add (IA32LI(0x80000000, TEMPREG9));	\
		ibb->add (IA32AND((a), TEMPREG9, TEMPREG4));	\
		ibb->add (IA32AND(TEMPREG3, TEMPREG9, TEMPREG6));	\
		ibb->add (CMP(NE, TEMPREG4, TEMPREG5, TEMPREG7));	\
		ibb->add (CMP(EQ, TEMPREG6, TEMPREG5, TEMPREG8));	\
		ibb->add (IA32AND(TEMPREG7, TEMPREG8, TEMPREG4));	\
		ibb->add (IA32LI(0x1, TEMPREG9));	\
		ibb->add (CMP(EQ, TEMPREG9, TEMPREG4, NOF));	\
		ibb->add (IA32PUT(NOF, NOF));

    void set_flags_subl(int a, int b)
    {
        int tmp = a - b;
        if ( (unsigned)a < (unsigned)b )
        {
            _regs[NCF] = 1;
        }
        else
        {
            _regs[NCF] = 0;
        }	

        if ( tmp == 0 )
        {
            _regs[NZF] = 1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ( (signed)tmp < 0 )
        {
            _regs[NSF] = 1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((a < 0 && b > 0) || (a > 0 && b < 0))
        {
            if ((tmp > 0 == b > 0) || (tmp < 0 == b < 0))
                _regs[NOF] = 1;
            else
                _regs[NOF] = 0;
        }
        else
        {
            _regs[NOF] = 0;
        }
    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_SUBW(a,b)	\
	ibb->add( IA32LI(0xffff, TEMPREG0) );	\
	ibb->add( IA32AND( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( IA32AND( (b), TEMPREG0, TEMPREG5 ) );	\
	ibb->add( IA32SUB( TEMPREG4, TEMPREG5, TEMPREG6 ) );	\
	ibb->add( CMP( BE, TEMPREG4, TEMPREG5, NCF ) );	\
	ibb->add( PUT( NCF, NCF, s32 ) );	\
	ibb->add( CMP( EQ, TEMPREG6, 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( CMP( LT, TEMPREG6, 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );	\
	ibb->add( CMP( LT, TEMPREG4, 0, TEMPREG7 ) );	\
	ibb->add( CMP( GT, TEMPREG5, 0, TEMPREG8 ) );	\
	ibb->add( CMP( GT, TEMPREG6, 0, TEMPREG9 ) );	\
	ibb->add( IA32AND( TEMPREG7, TEMPREG8, TEMPREG7 ) );	\
	ibb->add( IA32AND( TEMPREG7, TEMPREG9, TEMPREG7 ) );	\
	ibb->add( CMP( GT, TEMPREG4, 0, TEMPREG4 ) );	\
	ibb->add( CMP( LT, TEMPREG5, 0, TEMPREG5 ) );	\
	ibb->add( CMP( LT, TEMPREG6, 0, TEMPREG6 ) );	\
	ibb->add( IA32AND( TEMPREG4, TEMPREG5, TEMPREG4 ) );	\
	ibb->add( IA32AND( TEMPREG4, TEMPREG6, TEMPREG4 ) );	\
	ibb->add( IA32OR( TEMPREG4, TEMPREG7, NOF ) );	\
	ibb->add( PUT( NOF, NOF, s32 ) );

    void set_flags_subw(int a, int b)
    {
        short c = (short) (a & 0xffff);
        short d = (short) (b & 0xffff);

        short tmp = c - d;
        if ( (unsigned short)c < (unsigned short)d )
        {
            _regs[NCF]=1;
        }
        else
        {
            _regs[NCF] = 0;
        }	

        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }

        if ( (signed short)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((c < 0 && d > 0 && tmp > 0) || (c > 0 && d < 0 && tmp < 0))
        {
            _regs[NOF] = 1;
        }
        else
        {
            _regs[NOF] = 0;
        }

        // TODO AP, PF should be set
    }

	//added by zhangyichao, 2010-4-15
#define SET_FLAGS_SUBB(a,b)	\
	ibb->add( IA32LI(0xff, TEMPREG0) );	\
	ibb->add( IA32AND((a), TEMPREG0, (a)) );	\
	ibb->add( IA32AND((b), TEMPREG0, (b)) );	\
	ibb->add( IA32SUB((a), (b), TEMPREG3) );	\
	ibb->add( CMP(BE, (a), (b), NCF) );	\
	ibb->add( PUT(NCF, NCF, s32) );	\
	ibb->add( CMP(EQ, TEMPREG3, 0, NZF) );	\
	ibb->add( PUT(NZF, NZF, s32) );	\
	ibb->add( IA32LI(0x80, TEMPREG0) );	\
	ibb->add( IA32AND(TEMPREG3, TEMPREG0, TEMPREG4) );	\
	ibb->add( CMP(NE, TEMPREG4, 0, NSF) );	\
	ibb->add( PUT(NSF, NSF, s32) );	\
	ibb->add( IA32AND((a), TEMPREG0, TEMPREG5) );	\
	ibb->add( IA32AND((b), TEMPREG0, TEMPREG6) );	\
	ibb->add( CMP(NE, TEMPREG5, 0, TEMPREG5) );	\
	ibb->add( CMP(EQ, TEMPREG6, 0, TEMPREG6) );	\
	ibb->add( IA32AND(TEMPREG5, TEMPREG6, TEMPREG7) );	\
	ibb->add( IA32NOT(TEMPREG5, TEMPREG5) );	\
	ibb->add( IA32NOT(TEMPREG6, TEMPREG8) );	\
	ibb->add( IA32AND(TEMPREG5, TEMPREG8, TEMPREG8) );	\
	ibb->add( IA32OR(TEMPREG7, TEMPREG8, TEMPREG5) );	\
	ibb->add( CMP(EQ, TEMPREG4, 0, TEMPREG4) );	\
	ibb->add( CMP(EQ, TEMPREG4, TEMPREG6, TEMPREG7) );	\
	ibb->add( IA32NOT(TEMPREG4, TEMPREG4) );	\
	ibb->add( IA32NOT(TEMPREG6, TEMPREG6) );	\
	ibb->add( CMP(EQ, TEMPREG4, TEMPREG6, TEMPREG8) );	\
	ibb->add( IA32OR(TEMPREG7, TEMPREG8, TEMPREG6) );	\
	ibb->add( IA32AND(TEMPREG5, TEMPREG6, NOF) );	\
	ibb->add( PUT(NOF, NOF, s32) );

    void set_flags_subb(int a, int b)
    {
        a &= 0xff;
        b &= 0xff;

        int tmp = a - b;
        if ( (unsigned)a < (unsigned)b )
        {
            _regs[NCF]=1;
        }
        else
        {
            _regs[NCF] = 0;
        }	
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((tmp & 0x80) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((((a&0x80)!=0) && ((b&0x80)==0)) || (((a&0x80)==0) && ((b&0x80)!=0)))
        {
            if ( (((tmp&0x80)==0) == ((b&0x80)==0)) || (((tmp&0x80)!=0) == ((b&0x80)!=0)))
            {
                _regs[NOF] =  1;
            }
            else
            {
                _regs[NOF] = 0;
            }
        }
        else
        {
            _regs[NOF] = 0;
        }
    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_DECL1(a)	\
	ibb->add( IA32LI( 0x1, TEMPREG0 ) );	\
	ibb->add( IA32SUB( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( CMP( EQ, TEMPREG4, 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( CMP( LT, TEMPREG4, 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );	\
	ibb->add( CMP( LT, (a), 0, TEMPREG5 ) );	\
	ibb->add( CMP( GT, TEMPREG4, 0, TEMPREG6 ) );	\
	ibb->add( IA32AND( TEMPREG5, TEMPREG6, NOF ) );	\
	ibb->add( PUT( NOF, NOF, s32 ) );

    void set_flags_decl1(int a)
    {
        int tmp = a - 1;
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ( (signed)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if (a < 0 && tmp > 0)
        {
            _regs[NOF]=1;
        }
        else
        {
            _regs[NOF] = 0;
        }
    }

    void set_flags_decw1(int a)
    {
        short c = (short) ( a & 0xffff);
        short d = (short) (1);

        short tmp = c - d;
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ( (signed short)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((c < 0 && d > 0) || (c > 0 && d < 0))
        {
            if ((tmp > 0 == d > 0) || (tmp < 0 == d < 0))
                _regs[NOF]=1;
            else
                _regs[NOF] = 0;
        }
        else
        {
            _regs[NOF] = 0;
        }
    }

    void set_flags_decb1(int a)
    {
        a = (a & 0xff);

        int b = 1;
        int tmp = a - b;
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }

        if ((tmp & 0x80) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((((a&0x80)!=0) && ((b&0x80)==0)) || (((a&0x80)==0) && ((b&0x80)!=0)))
        {
            if ( (((tmp&0x80)==0) == ((b&0x80)==0)) || (((tmp&0x80)!=0) == ((b&0x80)!=0)))
            {
                _regs[NOF] = 1;
            }
            else
                _regs[NOF] = 0;
        }
        else
        {
            _regs[NOF] = 0;
        }
    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_ANDL(a)	\
	ibb->add( PUT( 0, NCF, s32 ) );	\
	ibb->add( PUT( 0, NOF, s32 ) );	\
	ibb->add( CMP( EQ, (a), 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( CMP( LT, (a), 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );

    void set_flags_andl(int a)
    {
        _regs[NCF] = 0;
        _regs[NOF] = 0;
        if ( a == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (signed)a < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        //TODO:set AF,PF according to the result
    }

    void set_flags_andw(int a)
    {
        a = a & 0xffff;
        _regs[NCF] = 0;
        _regs[NOF] = 0;
        if ( a == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (a & 0x8000) != 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        //TODO:set AF,PF according to the result
    }

// added by zhangyichao, 2010-5-17
#define SET_FLAGS_ANDB(a)	\
	ibb->add( IA32LI( 0xff, TEMPREG0 ) );	\
	ibb->add( IA32AND( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( PUT( 0, NCF, s32 ) );	\
	ibb->add( PUT( 0, NOF, s32 ) );	\
	ibb->add( CMP( EQ, TEMPREG4, 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( IA32LI( 0x80, TEMPREG0 ) );	\
	ibb->add( IA32AND( TEMPREG4, TEMPREG0, TEMPREG4 ) );	\
	ibb->add( CMP( NE, TEMPREG4, 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );
	// TODO: set AF, PF according to the result

    void set_flags_andb(int a)
    {
        a = a & 0xff;
        _regs[NCF] = 0;
        _regs[NOF] = 0;
        if ( a == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (a & 0x80) != 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        //TODO:set AF,PF according to the result
    }

    void set_flags_xorl(int a)
    {
        _regs[NCF] = 0;
        _regs[NOF] = 0;
        if ( a == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (signed)a < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        //TODO:set PF according to the result
        //TODO:AF is undefined
    }

    void set_flags_xorw(int a)
    {
        short b = (short) (a & 0xffff);
        _regs[NCF] = 0;
        _regs[NOF] = 0;
        if ( b == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if (b < 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        //TODO:set PF according to the result
        //TODO:AF is undefined
    }

    void set_flags_xorb(int a)
    {
        _regs[NCF] = 0;
        _regs[NOF] = 0;
        if ( (a&0xff) == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (a&0x80) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        //TODO:set PF according to the result
        //TODO:AF is undefined
    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_TESTL(a)	\
	ibb->add( PUT( 0, NCF, s32 ) );	\
	ibb->add( PUT( 0, NOF, s32 ) );	\
	ibb->add( CMP( EQ, (a), 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( CMP( LT, (a), 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );

    void set_flags_testl(int a)
    {
        _regs[NCF] = 0;
        _regs[NOF] = 0;

        if (a == 0)
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ((signed)a < 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        //TODO:set PF according to the result
        //TODO:AF is undefined
    }

// added by zhangyichao, 2010-5-19
#define SET_FLAGS_TESTB(a)	\
	ibb->add( PUT( 0, NCF, s32 ) );	\
	ibb->add( PUT( 0, NOF, s32 ) );	\
	ibb->add( IA32LI( 0xff, TEMPREG0 ) );	\
	ibb->add( IA32AND( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( CMP( EQ, TEMPREG4, 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( IA32LI( 0x80, TEMPREG0 ) );	\
	ibb->add( IA32AND( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( CMP( NE, TEMPREG4, 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );

    void set_flags_testb(int a)
    {
        _regs[NCF] = 0;
        _regs[NOF] = 0;
        if ( (a&0xff) == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ((a&0x80) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        //TODO:set PF according to the result
        //TODO:AF is undefined
    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_TESTW(a)	\
	ibb->add( PUT( 0, NCF, s32 ) );	\
	ibb->add( PUT( 0, NOF, s32 ) );	\
	ibb->add( IA32LI( 0xffff, TEMPREG0 ) );	\
	ibb->add( IA32AND( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( CMP( EQ, TEMPREG4, 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( IA32LI( 0x8000, TEMPREG0 ) );	\
	ibb->add( IA32AND( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( CMP( NE, TEMPREG4, 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );

    void set_flags_testw(int a)
    {
        _regs[NCF] = 0;
        _regs[NOF] = 0;

        if ( (a&0xffff) == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ((a&0x8000) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        //TODO:set PF according to the result
        //TODO:AF is undefined
    }

    void set_flags_rorl(unsigned int a, unsigned int b)
    {
        unsigned int c = ((a << (32-b)) & (a >> b));
        unsigned int d = ((c>>31) & 0x1);
        _regs[NCF] = d;

        if ( b == 1)
        {
            unsigned e = ((c>>30) & 0x1);

            if( (d==1&&e==0) || (d==0&&e==1))
                _regs[NOF] = 1;
            else
                _regs[NOF] = 0;
        }
    }

    void set_flags_rorw(unsigned int a, unsigned int b)
    {
        a = ( a & 0xffff);
        b = ( b & 0xffff);

        unsigned int c = ((a << (16-b)) & (a >> b));
        unsigned int d = ((c>>15) & 0x1);
        _regs[NCF] = d;

        if ( b == 1)
        {
            unsigned e = ((c>>14) & 0x1);

            if( (d==1&&e==0) || (d==0&&e==1))
                _regs[NOF] = 1;
            else
                _regs[NOF] = 0;
        }
    }


    void set_flags_roll(int a, int b)
    {
        int c = (a >> ( 32 - b));
        c = ( c & 0x1);

        _regs[NCF] = c;

        if (b == 1)
        {
            c = (a << b);
            c = (c >> 31);
            c = (c & 0x1);

            if ( (c==1&&_regs[NCF]==0) || (c==0&&_regs[NCF]==1))
            {
                _regs[NOF] = 1;
            }
            else
            {
                _regs[NOF] = 0;
            }
        }
    }

    void set_flags_shll1(int a, int b)
    {
        int tmp = a << b;

        if (b > 0)
        {
            _regs[NCF] = (((a << (b-1)) & 0x80000000) != 0);
        }
        if (b == 1)
        {
            int msb = ((a & 0x80000000) != 0);
            _regs[NOF] = (msb != _regs[NCF]);
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((tmp&0x80000000) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

    void set_flags_shlw(int a,int b)
    {
        a = (a & 0xffff);
        int tmp = a << b;

        if (b > 0)
        {
            _regs[NCF] = (((a << (b-1)) & 0x8000) != 0);
        }
        if (b == 1)
        {
            int msb = ((a & 0x8000) != 0);
            _regs[NOF] = (msb != _regs[NCF]);
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((tmp&0x8000) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

    void set_flags_shrl1(int a,int b)
    {
        int tmp = (unsigned)a >> b;

        if ( b > 0 )
        {
            _regs[NCF] = (((unsigned)a >> (b-1)) & 0x1);
        }
        if (b == 1)
        {
            _regs[NOF] = ((a & 0x80000000) != 0);
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((tmp & 0x80000000) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

    void set_flags_shrw(int a, int b)
    {
        a = (a & 0xffff);
        int tmp = (unsigned)a >> b;

        if ( b > 0 )
        {
            _regs[NCF] = (((unsigned)a >> (b-1)) & 0x1);
        }
        if (b == 1)
        {
            _regs[NOF] = ((a & 0x8000) != 0);
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((tmp & 0x8000) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

    void set_flags_shrb(int a, int b)
    {
        a = (a & 0xff);
        int tmp = (unsigned)a >> b;

        if ( b > 0 )
        {
            _regs[NCF] = (((unsigned)a >> (b-1)) & 0x1);
        }
        if (b == 1)
        {
            _regs[NOF] = ((a & 0x80) != 0);
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((tmp & 0x80) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

    void set_flags_sarl1(int a,int b)
    {
        int tmp = a >> b;

        if ( b > 0 )
        {
            _regs[NCF] = ((a >> (b-1)) & 0x1);
        }
        if (b == 1)
        {
            _regs[NOF] = 0;
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ( (signed)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

    void set_flags_sarw(int a,int b)
    {	
        a = a & 0xffff;
        int tmp = a >> b;

        if ( b > 0 )
        {
            _regs[NCF] = ((a >> (b-1)) & 0x1);
        }
        if (b == 1)
        {
            _regs[NOF] = 0;
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((a & 0x8000) != 0)
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

    void set_flags_sarb(int a,int b)
    {	
        a = a & 0xff;
        int tmp = a >> b;

        if ( b > 0 )
        {
            _regs[NCF] = ((a >> (b-1)) & 0x1);
        }
        if (b == 1)
        {
            _regs[NOF] = 0;
        }
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else 
        {
            _regs[NZF] = 0;
        }
        if ((a & 0x80) != 0)
        {
            _regs[NSF] = 1;
        }
        else
        {
            _regs[NSF] = 0;
        }
    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_IMULL(a)	\
	ibb->add( CMP( NE, (a), 0, TEMPREG4 ) );	\
	ibb->add( PUT( TEMPREG4, NCF, s32 ) );	\
	ibb->add( PUT( TEMPREG4, NOF, s32 ) );

    void set_flags_imull(int a)
    {	
        if(a == 0)
        {
            _regs[NCF] = 0;
            _regs[NOF] = 0;
        }
        else
        {
            _regs[NCF]=1;
            _regs[NOF]=1;
        }	
    }

    void set_flags_negl(int a)
    {
        int tmp = ~a + 1;

        if (a == 0)
            _regs[NCF] = 0;
        else
            _regs[NCF]=1;

        if (a == BX_MIN_BIT32S - 1) 		
            _regs[NOF]=1;
        else
            _regs[NOF] = 0;

        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (signed)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }
        //TODO:set AF,PF according to the result
    }

    void set_flags_shrdl1(int dest, int result, int count)
    {
        _regs[NCF] = ((dest >> (count - 1)) & 0x1);

        if (count == 1)
        {
            if ((dest > 0) != (result > 0))
                _regs[NOF]=1; 
            else
                _regs[NOF] = 0;
        }
        else
        {
            _regs[NOF] = 0;
        }

        if (result == 0)
            _regs[NZF]=1;
        else
            _regs[NZF]= 0;

        if (signed(result) < 0)
            _regs[NSF]=1;
        else
            _regs[NSF] = 0;
    }

    void set_flags_shldl(int dest, int result, int count)
    {
        _regs[NCF] =((dest << (count - 1)) & 0x80000000); 

        if (count == 1)
        {
            if ((dest > 0) != (result > 0))	    //sign change
                _regs[NOF]=1; 
            else
                _regs[NOF] = 0;
        }

        if (result == 0)
            _regs[NZF]=1;
        else
            _regs[NZF]=0;

        if (signed(result) < 0)
            _regs[NSF]=1;
        else
            _regs[NSF]=0;

    }

// added by zhangyichao, 2010-5-20
#define SET_FLAGS_INCL1(a)	\
	ibb->add( IA32LI( 0x1, TEMPREG0 ) );	\
	ibb->add( IA32ADD( (a), TEMPREG0, TEMPREG4 ) );	\
	ibb->add( CMP( EQ, TEMPREG4, 0, NZF ) );	\
	ibb->add( PUT( NZF, NZF, s32 ) );	\
	ibb->add( CMP( LT, TEMPREG4, 0, NSF ) );	\
	ibb->add( PUT( NSF, NSF, s32 ) );	\
	ibb->add( CMP( GT, (a), 0, TEMPREG5 ) );	\
	ibb->add( IA32AND( NSF, TEMPREG5, NOF ) );	\
	ibb->add( PUT( NOF, NOF, s32 ) );

    void set_flags_incl1(int a)
    {
        int tmp = a + 1;
        if ( tmp == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (signed)tmp < 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((signed)a > 0 && (signed)tmp < 0)
            _regs[NOF] = 1;
        else
            _regs[NOF] = 0;
    }

    void set_flags_incb1(int a)
    {
        int tmp = a + 1;
        if ( (tmp&0xff) == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (tmp&0x80) != 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((a&0x80) == 0 && (tmp&0x80) != 0)
            _regs[NOF] = 1;
        else
            _regs[NOF] = 0;
    }

    void set_flags_incw1(int a)
    {
        int tmp = a + 1;
        if ( (tmp&0xffff) == 0 )
        {
            _regs[NZF]=1;
        }
        else
        {
            _regs[NZF] = 0;
        }

        if ( (tmp&0x8000) != 0 )
        {
            _regs[NSF]=1;
        }
        else
        {
            _regs[NSF] = 0;
        }

        if ((a&0x8000) == 0 && (tmp&0x8000) != 0)
            _regs[NOF] = 1;
        else
            _regs[NOF] = 0;
    }

    void set_flags_sahf(int a)
    {
        _regs[NCF] = ((a & 0x100) != 0);
        _regs[NPF] = ((a & 0x400) != 0);
        _regs[NAF] = ((a & 0x1000) != 0);
        _regs[NZF] = ((a & 0x4000) != 0);
        _regs[NSF] = ((a & 0x8000) != 0);
    }
}


using namespace crossbit;

InterpMode IA32Interpreter::mode_ = NORMAL;

XTRegNum IA32Interpreter::resolveModRM(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(hyn_msg) printf("===========resolveModRM==============\n");
    BlockSize op_size_save = op_size;
    DataType dtype_save = dtype;
    op_size = WORD;
    dtype = s32;
    switch (insn->mod)
    {
        case 0:
            if(hyn_msg) printf("Mod == 00\n");
            switch (insn->rm)
            {
                //has S-I-B byte
                case 4:
                    if(hyn_msg) printf("RM == 100\n");
                    if(insn->index == 4)
                    {
                        if(hyn_msg) printf("index == 100\n");
                        ibb->add (IA32GET(insn->base, VREG(insn->base)));

                        op_size = op_size_save;
                        dtype = dtype_save;

                        return VREG(insn->base);
                    }
                    else
                    {
                        if(hyn_msg) printf("index != 100\n");
                        ibb->add (IA32GET(insn->index, VREG(insn->index)));
                        ibb->add (IA32LI(insn->scale, TEMPREG1));
                        ibb->add (IA32SLL(VREG(insn->index), TEMPREG1, MODRMREG));
                        if(insn->base == 5)
                        {
                            if(hyn_msg) printf("base == 101\n");
                            ibb->add (IA32ADDI(MODRMREG, insn->displacement.displ32, MODRMREG));
                        }
                        else
                        {
                            if(hyn_msg) printf("base != 101\n");
                            ibb->add (IA32GET(insn->base, VREG(insn->base)));
                            ibb->add (IA32ADD(MODRMREG, VREG(insn->base), MODRMREG));
                        }

                        op_size = op_size_save;
                        dtype = dtype_save;
                        return MODRMREG;
                    }
                    break;
                case 5:
                    {
                        if(hyn_msg) printf("RM == 101\n");
                        ibb->add (IA32LI(insn->displacement.displ32, MODRMREG));

                        op_size = op_size_save;
                        dtype = dtype_save;
                        return MODRMREG;
                    }
                default:
                    {
                        if(hyn_msg) printf("RM == default\n");
                        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                        //ibb->add (IA32MOV(VREG(insn->rm), MODRMREG));

                        op_size = op_size_save;
                        dtype = dtype_save;
                        //return MODRMREG;
                        return VREG(insn->rm);
                    }
            }
            break;
        case 1:
        case 2:
            if(hyn_msg) printf("Mod == 10\n");
            if (insn->rm == 4)				//has S-I-B byte
            {
                if(hyn_msg) printf("RM == 100\n");
                if(insn->index == 4)
                {		//Only (base+disp)
                    if(hyn_msg) printf("index == 100\n");
                    ibb->add (IA32GET(insn->base, VREG(insn->base)));
                    ibb->add (IA32LI(insn->displacement.displ32, MODRMREG));
                    ibb->add (IA32ADD(MODRMREG, VREG(insn->base), MODRMREG));

                    op_size = op_size_save;
                    dtype = dtype_save;
                    return MODRMREG;
                }
                else
                {		// (base + index * scale + disp)
                    if(hyn_msg) printf("index != 100\n");
                    ibb->add (IA32GET(insn->index, VREG(insn->index)));
                    ibb->add (IA32LI((Word)insn->scale, TEMPREG1));
                    ibb->add (IA32SLL(VREG(insn->index), TEMPREG1, MODRMREG));
                    ibb->add (IA32GET(insn->base, VREG(insn->base)));
                    ibb->add (IA32ADD(MODRMREG, VREG(insn->base), MODRMREG));
                    ibb->add (IA32ADDI(MODRMREG, insn->displacement.displ32, MODRMREG));

                    op_size = op_size_save;
                    dtype = dtype_save;
                    return MODRMREG;
                }
            }
            else
            {
                if(hyn_msg) printf("RM != 100\n");
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(insn->displacement.displ32, MODRMREG));
                ibb->add (IA32ADD(MODRMREG, VREG(insn->rm), MODRMREG));

                op_size = op_size_save;
                dtype = dtype_save;
                return MODRMREG;
            }
            break;
        case 3:
            {
                if(hyn_msg) printf("Mod == 11\n");
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (IA32MOV(VREG(insn->rm), MODRMREG));

                op_size = op_size_save;
                dtype = dtype_save;
                return VREG(insn->rm);
            }
    }
    if(segOver)
    {
        op_size = HALFWORD;
        dtype = s16;
        ibb->add (IA32GET(segReg, t2));
        ibb->add (IA32LI ((Word)state_,t3));
		// commented by zhangyichao, 2010-5-20, because the set_seg_base is empty
        //ibb->add (CALL((Word)(&crossbit::set_seg_base),2,t3,t2));
        op_size = WORD;
        dtype = s32;
        ibb->add (IA32GET(SEG_BASE, t2));
        ibb->add (IA32ADD(t2,t1,t1));
    }
    op_size = op_size_save;
    dtype = dtype_save;

    ibb->add (IA32MOV(t1, MODRMREG));
    return MODRMREG;

}

//0f b1 Ia_cmpxchg_Ed_Gd
void IA32Interpreter::rorm_r_cmpxchg(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    printf("cmpxchg\n");
    exit(0);
}

//A1 Ia_movw_AX_Ow
void IA32Interpreter::AX_Ow_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("AX_Ow_movw\n");
    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
    ibb->add (LD(TEMPREG1, 0, TEMPREG1, dtype));

    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
    ibb->add (IA32LI(0xffff0000, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//A3 Ia_movw_Ow_AX 
void IA32Interpreter::Ow_AX_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("Ow_AX_movw\n");
    //op_size = HALFWORD;
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI(op->op1.imm, TEMPREG1));
    ibb->add (ST(VREG(IA32ProcessorState::EAX), TEMPREG1, 0, s16));
}

//89 Ia_movw_Ew_Gw
void IA32Interpreter::rorm_r_movw89(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_movw89\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (ZEXT(VREG(op->op2.reg), TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (ST(VREG(op->op2.reg), t, 0, s16));
    }
}

//89 Ia_movl_Ed_Gd
void IA32Interpreter::rorm_r_movl89(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_movl89\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32MOV(VREG(op->op2.reg), VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (ST(VREG(op->op2.reg), t, 0, s32));
    }
}

//8E Ia_movw_Sw_Ew
void IA32Interpreter::r_r_movw8e(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("r_r_movw8e\n");
    XTRegNum t = resolveModRM(insn,op,bb);
    op_size = HALFWORD;
    dtype = s16;
    if (insn->mod == 3)
    {
        //Note:t2 is a XTRegNum(=insn->rm) while mod == 3
        ibb->add (IA32GET(insn->rm,t2));
        ibb->add (IA32PUT(t2,insn->nnn+SR));//segment register
    }
    else
    {
        printf("should not be here!\n");
    }
}

//8D /r Ia_leal_Gd_Md
void IA32Interpreter::r_m_leal(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_m_leal\n");

	XTRegNum t = resolveModRM(insn,op,bb);

	ibb->add (IA32MOV(t, VREG(op->op1.reg)));
	ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

//E9 Ia_jmp_Jd
void IA32Interpreter::i_jmpd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jmpd\n");
    //ibb->add(JMP(0, op->op1.imm)); 
    insn->ilen = op->op1.imm - curNext;
}

//FF /4  Ia_jmp_Ed
void IA32Interpreter::rorm_jmpd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("rorm_jmpd at 0x%x\n", curNext);
    if(ptx_msg) printf("rorm_jmpd\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (JMP(VREG(insn->rm), 0)); 
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (JMP(TEMPREG1, 0)); 
    }
}

//0F 94 Ia_setz_Eb
void IA32Interpreter::rorm_setz(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setz\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));

        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s8));
    }
}

// OF 92 Ia_setb_Eb
void IA32Interpreter::rorm_setb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setb\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);

        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s8));
    }
}

// 0f 96 Ia_setbe_Eb
void IA32Interpreter::rorm_setbe(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setbe\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        ibb->add (IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));

        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        ibb->add (IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));

        ibb->add(ST(TEMPREG1, t, 0, s8));
    }
}

// added by chuchao, 3.25
// 0F 93 Ia_setnb_Eb
void IA32Interpreter::rorm_setnb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setnb\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        // ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        // ibb->add (IA32OR(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(1, TEMPREG2));
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG3, TEMPREG2));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);

        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        // ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        // ibb->add (IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (IA32LI(1, TEMPREG2));
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s8));
    }
}


// 0F 97 Ia_setnbe_Eb
void IA32Interpreter::rorm_setnbe(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setnbe\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        ibb->add (IA32OR(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (IA32SUB(TEMPREG1, TEMPREG2, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);

        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        ibb->add (IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (IA32LI(1, TEMPREG2));
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s8));
    }
}

// 0F 9C Ia_setl_Eb 
void IA32Interpreter::rorm_setl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));

        ibb->add(ST(TEMPREG1, t, 0, s8));
    }
}

// 0F 9E Ia_setle_Eb
void IA32Interpreter::rorm_setle(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setle\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        ibb->add (IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
        ibb->add (IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));

        ibb->add(ST(TEMPREG1, t, 0, s8));
    }
}

// 0F 9D Ia_setnl_Eb
void IA32Interpreter::rorm_setnl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setnl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG3));

        ibb->add (ST(TEMPREG3, t, 0, s8));
    }
}

// checkpoint

// 0F 9F Ia_setnel_Eb 
void IA32Interpreter::rorm_setnle(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setnle\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG3));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
        ibb->add (IA32LI(1, TEMPREG2));
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32AND(TEMPREG2, TEMPREG3, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
        ibb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG3));
        ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
        ibb->add (IA32LI(1, TEMPREG2));
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32AND(TEMPREG2, TEMPREG3, TEMPREG2));

        ibb->add(ST(TEMPREG2, t, 0, s8));
    }
}

//3D /id Ia_cmpw_AX_Iw
void IA32Interpreter::AX_i_cmpw3d(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("AX_i_cmpw3d\n");
    // op_size = HALFWORD;
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
    //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
	SET_FLAGS_SUBW( VREG(IA32ProcessorState::EAX), TEMPREG1 );
}

//39 /r Ia_cmpw_Ew_Gw
void IA32Interpreter::rorm_r_cmpw39(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_cmpw39\n");
    if (insn->mod == 3)
    {
        //op_size = HALFWORD;
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), VREG(op->op2.reg)));
		SET_FLAGS_SUBW( VREG(insn->rm), VREG(op->op2.reg) );
	}
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        //op_size = HALFWORD;
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));

        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG1, VREG(op->op2.reg)));
		SET_FLAGS_SUBW( TEMPREG1, VREG(op->op2.reg) );
    }
}

// 81 /7 iw Ia_cmpw_Ew_Iw
void IA32Interpreter::rorm_i_cmpw81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_cmpw81\n");
    if (insn->mod == 3)
    {
        //op_size = HALFWORD;
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));

        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), TEMPREG1));
		SET_FLAGS_SUBW( VREG(insn->rm), TEMPREG1 );
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));

        ibb->add (LD(t, 0, TEMPREG2, s16));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG2, TEMPREG1));
		SET_FLAGS_SUBW( TEMPREG2, TEMPREG1 );
    }
}

// 83 /7 ib Ia_cmpw_Ew_sIb
void IA32Interpreter::rorm_i_cmpw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_cmpw83\n");
    if (insn->mod == 3)
    {
        //op_size = HALFWORD;
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), TEMPREG1));
		SET_FLAGS_SUBW( VREG(insn->rm), TEMPREG1 );
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG2, TEMPREG1));
		SET_FLAGS_SUBW( TEMPREG2, TEMPREG1 );
    }
}

//3B /r Ia_cmpw_Gw_Ew
void IA32Interpreter::r_rorm_cmpw3b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_i_cmpw3b\n");
    if (insn->mod == 3)
    {
        //op_size = HALFWORD;
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), VREG(insn->rm)));
		SET_FLAGS_SUBW( VREG(op->op1.reg), VREG(insn->rm) );
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        //op_size = HALFWORD;
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), TEMPREG1));
		SET_FLAGS_SUBW( VREG(op->op1.reg), TEMPREG1 );
    }
}

//39 /r Ia_cmpl_Ed_Gd 
void IA32Interpreter::rorm_r_cmpl39(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_cmpl39\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), VREG(op->op2.reg)));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(insn->rm), VREG(op->op2.reg))
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG1, VREG(op->op2.reg)));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(TEMPREG1, VREG(op->op2.reg))
    }
}

//3B /r Ia_cmpl_Gd_Ed 
void IA32Interpreter::r_rorm_cmpl3b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_cmpl3b\n");

	if (insn->mod == 3)
	{
		ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), VREG(insn->rm)));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(op->op1.reg), VREG(insn->rm));
	}
	else
	{
		XTRegNum t = resolveModRM(insn,op,bb);
		ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		ibb->add (LD(t, 0, TEMPREG1, s32));
		//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(op->op1.reg), TEMPREG1);
	}
}

//81 /7 id Ia_cmpl_Ed_Id
void IA32Interpreter::rorm_i_cmpl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_cmpl81\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(insn->rm), TEMPREG1);
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(TEMPREG2, TEMPREG1);
	}
}

//83 /7 Ia_cmpl_Ed_sIb
void IA32Interpreter::rorm_i_cmpl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_cmpl83\n");
	if (insn->mod == 3)
	{
		ibb->add (IA32LI(op->op2.imm, TEMPREG1));
		ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(insn->rm), TEMPREG1);
	}
	else
	{
		XTRegNum t = resolveModRM(insn,op,bb);
		ibb->add (IA32LI(op->op2.imm, TEMPREG2));
		ibb->add (LD(t, 0, TEMPREG1, s32));
		//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG1, TEMPREG2));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(TEMPREG1, TEMPREG2);
	}
}

//38 /7 Ia_cmpb_Eb_Gb
void IA32Interpreter::rorm_r_cmpb38(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
	if(ptx_msg) printf("rorm_r_cmpb38\n");
	if (insn->mod == 3)
	{
		if (op->op2.reg < 4)
		{
			ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), VREG(op->op2.reg)));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(VREG(insn->rm), VREG(op->op2.reg))
            }
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, VREG(op->op2.reg)));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(TEMPREG2, VREG(op->op2.reg))
            }
        }
        else
        {
            op->op2.reg -= 4;

            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG2));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(VREG(insn->rm), TEMPREG2)
            }
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                //ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG3));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG3, TEMPREG2));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(TEMPREG1, TEMPREG2)
            }
        }
    }
    else
    {
        if (op->op2.reg < 4)
        {

            XTRegNum t = resolveModRM(insn,op,bb);

            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, VREG(op->op2.reg)));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(TEMPREG1, VREG(op->op2.reg))
		}
        else
        {
            op->op2.reg -= 4;

            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, TEMPREG2));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(TEMPREG1, TEMPREG2)
		}
    }
}

// 3A /r Ia_cmpb_Gb_Eb
void IA32Interpreter::r_rorm_cmpb3a(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_cmpb3a\n");
    if (insn->mod == 3)
    {
        if (op->op1.reg < 4)
        {
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(op->op1.reg), VREG(insn->rm)));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(VREG(op->op1.reg), VREG(insn->rm))
			}
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(op->op1.reg), TEMPREG2));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(VREG(op->op1.reg), TEMPREG2)
			}
        }
        else
        {
            op->op1.reg -= 4;
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG2));

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, VREG(insn->rm)));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(TEMPREG2, VREG(insn->rm))
			}
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG3));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG3));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(TEMPREG2, TEMPREG1)
            }
        }
    }
    else
    {
        if (op->op1.reg < 4)
        {
            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(op->op1.reg), TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(VREG(op->op1.reg), TEMPREG1)
		}
        else
        {
            XTRegNum t = resolveModRM(insn,op,bb);

            op->op1.reg -= 4;
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG2));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(TEMPREG2, TEMPREG1)
		}
    }
}

//80 /7 Ia_cmpb_Eb_Ib
void IA32Interpreter::rorm_i_cmpb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_cmpb80\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));

        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(VREG(insn->rm), TEMPREG1);
		}
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG2));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG3, TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(TEMPREG2, TEMPREG1);
		}
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));
		// added by zhangyichao, 2010-4-15
		SET_FLAGS_SUBB(TEMPREG2, TEMPREG1);
	}
}

//0F 85 Ia_jne_Jd		(ZF == 0)
void IA32Interpreter::i_jned(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jned\n");
    ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
    ibb->add (BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

// 7C Ia_jl_Jb
void IA32Interpreter::i_jlb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jlb\n");
    ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG2));
    ibb->add (BRANCH(NE, TEMPREG1, TEMPREG2, 0, op->op1.imm));	
}

// 0F 8C Ia_jl_Jd
void IA32Interpreter::i_jld(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jld\n");
    ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG2));
    ibb->add (BRANCH(NE, TEMPREG1, TEMPREG2, 0, op->op1.imm));	
}

//0F 8E Ia_jle_Jd		(ZF == 1 or SF != OF)
void IA32Interpreter::i_jled(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jled\n");
    ibb->add (IA32GET(IA32ProcessorState::OF, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG2));
    ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG3));
    ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));
    ibb->add (IA32OR(TEMPREG1, TEMPREG3, TEMPREG1));
    ibb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));	
}

//7E Ia_jle_Jb
void IA32Interpreter::i_jleb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jleb\n");
    i_jled(insn, op, bb);
}

//85 /r Ia_testl_Ed_Gd
void IA32Interpreter::rorm_r_testl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_testl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

        if ((op->op2.reg) == (insn->rm))
        {
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testl), 1, VREG(op->op2.reg)));
				SET_FLAGS_TESTL( VREG(op->op2.reg) );
			}
        }
        else
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));
				SET_FLAGS_TESTL( TEMPREG1 );
			}
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));
			SET_FLAGS_TESTL( TEMPREG1 );
		}
	}
}

//85 /r Ia_testw_Ew_Gw
void IA32Interpreter::rorm_r_testw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_testw\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

        if ((op->op2.reg) == (insn->rm))
        {
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testw), 1, VREG(op->op2.reg)));
				SET_FLAGS_TESTW( VREG(op->op2.reg) );
			}
        }
        else
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
				SET_FLAGS_TESTW( TEMPREG1 );
			}
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (IA32AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
			SET_FLAGS_TESTW( TEMPREG1 );
		}
	}
}

//F7 /0 iw Ia_testw_Ew_Iw
void IA32Interpreter::rorm_i_testw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_testw\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
			SET_FLAGS_TESTW( TEMPREG1 );
		}
	}
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
			SET_FLAGS_TESTW( TEMPREG1 );
		}
	}
}

//A8 ib Ia_testb_AL_Ib
void IA32Interpreter::AL_i_testb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
	if(ptx_msg) printf("AL_i_testb\n");
	ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	ibb->add (IA32LI (op->op2.imm, TEMPREG1));
	ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
		SET_FLAGS_TESTB( TEMPREG1 );
	}
}

// A9 id Ia_testl_EAX_Id
void IA32Interpreter::EAX_i_testl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("EAX_i_testl\n");
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI (op->op2.imm, TEMPREG1));
    ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));	
		SET_FLAGS_TESTL( TEMPREG1 );
	}
}

//F6 /0 ib Ia_testb_Eb_Ib
void IA32Interpreter::rorm_i_testb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_testb\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI (op->op2.imm, TEMPREG1));

        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));	
				SET_FLAGS_TESTB( TEMPREG1 );
			}
		}
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
            ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
				SET_FLAGS_TESTB( TEMPREG1 );
			}
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32LI (op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));	
			SET_FLAGS_TESTB( TEMPREG1 );
		}
	}
}

//F7 /0 Ia_testl_Ed_Id
void IA32Interpreter::rorm_i_testl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_testl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));	
			SET_FLAGS_TESTL( TEMPREG1 );
		}
	}
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));	
			SET_FLAGS_TESTL( TEMPREG1 );
		}
    }
}

//74 Ia_jz_Jb				(ZF == 1)
void IA32Interpreter::i_jzb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jzb\n");
    ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
    ibb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//EB Ia_jmp_Jb
void IA32Interpreter::i_jmpb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jmpb\n");
    //ibb->add(JMP(0, op->op1.imm));
    insn->ilen = op->op1.imm - curNext;
}

//72 Ia_jb_Jb  Note: jb is the same meaning of jc.The last letter b is the imm size of the insn
void IA32Interpreter::i_jbb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jbb\n");
    ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    ibb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

// 0F 82 Ia_jb_Jd  
// Note: jb is the same meaning of jc.The last letter b is the imm size of the insn
void IA32Interpreter::i_jbd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jbd\n");
    ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    ibb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

// 78 cb Ia_js_Jb  
void IA32Interpreter::i_jsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jsb\n");

    ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    ibb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//OF 88 cb Ia_js_Jd  
void IA32Interpreter::i_jsd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jsd\n");
    ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    ibb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//79 cb Ia_jns_Jb  
void IA32Interpreter::i_jnsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnsb\n");
    ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    ibb->add (BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

// 0F 89 Ia_jns_Jd  
void IA32Interpreter::i_jnsd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnsd\n");
    ibb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    ibb->add (BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

// 30 /r Ia_xorb_Eb_Gb
void IA32Interpreter::rorm_r_xorb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_xorb\n");
    if (insn->mod == 3)
    {
        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32XOR(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
                ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
                ibb->add (IA32LI(0xff, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -=4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                ibb->add (IA32XOR(TEMPREG2, VREG(op->op2.reg), TEMPREG2));
                ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG2));

                ibb->add (IA32LI(0xffff00ff, TEMPREG1));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
        else
        {
            op->op2.reg -=4;
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32XOR(VREG(insn->rm), TEMPREG3, TEMPREG1));
                ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));

                ibb->add (IA32LI(0xff, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -=4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                ibb->add (IA32XOR(TEMPREG2, TEMPREG3, TEMPREG2));
                ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG2));

                ibb->add (IA32LI(0xffff00ff, TEMPREG1));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            ibb->add (IA32XOR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
            ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
        else
        {
            op->op2.reg -=4;
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
            ibb->add (LD(t, 0, TEMPREG1, s8));

            ibb->add (IA32XOR(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
    }
}

// 80 /6 ib Ia_xorb_Eb_ib
void IA32Interpreter::rorm_i_xorb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_i_xorb\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));

        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32XOR(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG2));
            ibb->add (IA32LI(0xff, TEMPREG1));
            ibb->add (IA32AND(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
            ibb->add (IA32XOR(TEMPREG3, TEMPREG1, TEMPREG3));
            ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG3));

            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (ZEXT(TEMPREG3, TEMPREG2, b8));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));

        ibb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s8));
    }
}

//31 Ia_xorl_Ed_Gd
void IA32Interpreter::rorm_r_xorl31(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_xorl31\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32XOR(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(insn->rm)));
		}
		ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32XOR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, TEMPREG1));
		}
        ibb->add (ST(TEMPREG1, t, 0, s32));
    }
}

//81 Ia_xorl_Ed_Id
void IA32Interpreter::rorm_r_xorl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_xorl81\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32XOR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(insn->rm)));
		}
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, TEMPREG1));
		}
        ibb->add (ST(TEMPREG1, t, 0, s32));
    }
}

//33 Ia_xorl_Gd_Ed
void IA32Interpreter::r_rorm_xorl33(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_xorl33\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32XOR(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(op->op1.reg)));
		}
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32XOR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(op->op1.reg)));
		}
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//83 Ia_xorl_Ed_sIb
void IA32Interpreter::rorm_i_xorl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_xorl83\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32XOR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(insn->rm)));
		}
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32XOR(TEMPREG1, TEMPREG2, TEMPREG1));

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, TEMPREG1));
		}
        ibb->add (ST(TEMPREG1, t, 0, s32));
    }
}

//31 Ia_xorw_Ew_Gw
void IA32Interpreter::rorm_r_xorw31(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_r_xorw31\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32XOR(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));

        ibb->add (CALL((Word)(&crossbit::set_flags_xorw), 1, TEMPREG1));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (IA32XOR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));

        ibb->add (CALL((Word)(&crossbit::set_flags_xorw), 1, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s16));
    }
}

//40+rd Ia_incl_ERX
void IA32Interpreter::r_incl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("r_incl\n");
	if( mode_ == NORMAL )
	{
		ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

		//ibb->add (CALL((Word)(&crossbit::set_flags_incl1), 1, VREG(op->op1.reg)));
		SET_FLAGS_INCL1( VREG(op->op1.reg) );
		ibb->add (IA32ADDI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
		ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else if( mode_ == PTX )
	{
		ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

		ibb->add (IA32ADDI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
		ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
		UTIL::XTLOG("Unknown interp mode!\n");
		exit(0);
	}
}

// FE /0 Ia_incb_Eb
void IA32Interpreter::rorm_incb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_incb\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (CALL((Word)(&crossbit::set_flags_incb1), 1, VREG(insn->rm)));

            ibb->add (IA32ADDI(VREG(insn->rm), 1, TEMPREG1));
            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -=4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (CALL((Word)(&crossbit::set_flags_incb1), 1, TEMPREG2));

            ibb->add (IA32ADDI(TEMPREG2, 1, TEMPREG2));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));
        ibb->add (CALL((Word)(&crossbit::set_flags_incb1), 1, TEMPREG1));

        ibb->add (IA32ADDI(TEMPREG1, 1, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s8));	
    }
}

//FF /0  Ia_incl_Ed
void IA32Interpreter::rorm_incl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_incl\n");
    if(mode_ == NORMAL)
    {
        if (insn->mod == 3)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            //ibb->add (CALL((Word)(&crossbit::set_flags_incl1), 1, VREG(insn->rm)));
			SET_FLAGS_INCL1( VREG(insn->rm) );

            ibb->add (IA32ADDI(VREG(insn->rm), 1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (LD(t, 0, TEMPREG1, s32));
            //ibb->add (CALL((Word)(&crossbit::set_flags_incl1), 1, TEMPREG1));
			SET_FLAGS_INCL1( TEMPREG1 );

            ibb->add (IA32ADDI(TEMPREG1, 1, TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s32));	
        }
    }
    else if(mode_ == PTX)
    {
        if (insn->mod == 3)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

            ibb->add (IA32ADDI(VREG(insn->rm), 1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (LD(t, 0, TEMPREG1, s32));

            ibb->add (IA32ADDI(TEMPREG1, 1, TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s32));	
        }
    }
    else
    {
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
    }
}

// FF /0  Ia_incl_Ew
void IA32Interpreter::rorm_incw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_incw\n");

    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_incw1), 1, VREG(insn->rm)));

        ibb->add (IA32ADDI(VREG(insn->rm), 1, TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (CALL((Word)(&crossbit::set_flags_incw1), 1, TEMPREG1));

        ibb->add (IA32ADDI(TEMPREG1, 1, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s16));
    }
}

// 40 + rw Ia_incw_RX
void IA32Interpreter::r_incw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_incl\n");
    ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    ibb->add (CALL((Word)(&crossbit::set_flags_incw1), 1, VREG(op->op1.reg)));

    ibb->add (IA32ADDI(VREG(op->op1.reg), 1, TEMPREG1));
    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
    ibb->add (IA32LI(0xffff0000, TEMPREG2));
    ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

// FF /1 Ia_decw_Ew
void IA32Interpreter::rorm_decw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_decw\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_decw1), 1, VREG(insn->rm)));

        ibb->add (IA32SUBI(VREG(insn->rm), 1, TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (CALL((Word)(&crossbit::set_flags_decw1), 1, TEMPREG1));

        ibb->add (IA32SUBI(TEMPREG1, 1, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s16));	
    }
}

// 48 + rw Ia_decw_RX
void IA32Interpreter::decw_rx(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("decw_rx\n");
    ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    ibb->add (CALL((Word)(&crossbit::set_flags_decw1), 1, VREG(op->op1.reg)));

    ibb->add (IA32SUBI(VREG(op->op1.reg), 1, TEMPREG1));
    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
    ibb->add (IA32LI(0xffff0000, TEMPREG2));
    ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

//FE Ia_decb_Eb
void IA32Interpreter::rorm_decb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_decb\n");
    //op_size = BYTE;
    if (insn->mod == 3)
    {

        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (CALL((Word)(&crossbit::set_flags_decb1), 1, VREG(insn->rm)));

            ibb->add (IA32SUBI(VREG(insn->rm), 1, TEMPREG1));
            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -=4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (CALL((Word)(&crossbit::set_flags_decb1), 1, TEMPREG2));

            ibb->add (IA32SUBI(TEMPREG2, 1, TEMPREG2));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));
        ibb->add (CALL((Word)(&crossbit::set_flags_decb1), 1, TEMPREG1));

        ibb->add (IA32SUBI(TEMPREG1, 1, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s8));
    }
}

// A0 Ia_movb_AL_Ob
void IA32Interpreter::Ob_movb_AL(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("Ob_movb_AL\n");
    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
    ibb->add (LD(TEMPREG1, 0, TEMPREG1, s8));
    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI(0xffffff00, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//A2 Ia_movb_Ob_AL
void IA32Interpreter::AL_movb_Ob(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("AL_movb_Ob\n");
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI(op->op1.imm, TEMPREG1));
    ibb->add (ST(VREG(IA32ProcessorState::EAX), TEMPREG1, 0, s8));
}

//8A /r  Ia_movb_Gb_Eb
void IA32Interpreter::r_rorm_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movb\n");
    if (insn->mod == 3)
    {
        if (op->op1.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0xff, TEMPREG1));
                ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (ZEXT(VREG(insn->rm), TEMPREG1, b16));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(TEMPREG1, TEMPREG2, TEMPREG1));

                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
        else
        {
            op->op1.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0xff, TEMPREG1));
                ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0xff00, TEMPREG1));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, TEMPREG2));

                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0xffff00ff, TEMPREG1));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));

        if (op->op1.reg < 4)
        {
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            op->op1.reg -= 4;
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG2));
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
}

//C6 /0 Ia_movb_Eb_Ib
void IA32Interpreter::rorm_i_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_movb\n");
    //op_size = BYTE;

    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32LI(op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32LI((op->op2.imm << 8), TEMPREG1));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s8));
    }
}

//88 /r Ia_movb_Eb_Gb
void IA32Interpreter::rorm_r_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_movb\n");
    //op_size = BYTE;
    if (insn->mod == 3)
    {
        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (ZEXT(VREG(op->op2.reg), TEMPREG1, b8));

            if (op->op1.reg < 4)
            {
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                op->op1.reg -=4;
                ibb->add (IA32LI(0x8, TEMPREG3));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG3, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
        else
        {
            op->op2.reg -=4;
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            if (op->op1.reg < 4)
            {
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xff, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                op->op1.reg -=4;
                ibb->add (IA32LI(0xff00, TEMPREG3));
                ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (ST(VREG(op->op2.reg), t, 0, s8));
        }
        else
        {
            op->op2.reg -=4;
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
    }
}

//B0-B7 Ia_movb_R8_Ib
void IA32Interpreter::r_i_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("r_i_movb\n");
    if (op->op1.reg < 4)
    {
        ibb->add (IA32LI ((Word)op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32LI(0xffffff00, TEMPREG2));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        op->op1.reg -= 4;
        ibb->add (IA32LI((Word)(op->op2.imm << 8), TEMPREG1));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32LI(0xffff00ff, TEMPREG2));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// A5 Ia_movsl_Yd_Xd
void IA32Interpreter::movsl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("movsl\n");

    ibb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    ibb->add (USE(IA32ProcessorState::ESI));
    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0));
    }

    ibb->add (LD(VREG(IA32ProcessorState::ESI), 0, TEMPREG1, s32));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESI), 4, VREG(IA32ProcessorState::ESI)));
    ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::EDI), 0, s32));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 4, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        ibb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// A5 Ia_movsw_Yw_Xw
void IA32Interpreter::movsw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("movsw\n");
    op_size = WORD;
    dtype = s32;

    ibb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    ibb->add (USE(IA32ProcessorState::ESI));
    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0));
    }

    ibb->add (LD(VREG(IA32ProcessorState::ESI), 0, TEMPREG1, s16));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESI), 2, VREG(IA32ProcessorState::ESI)));
    ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::EDI), 0, s16));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 2, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        ibb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// AA Ia_stosb_Yb_AL
void IA32Interpreter::stosb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("stosb\n");
    op_size = WORD;
    dtype = s32;

    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (USE(IA32ProcessorState::EAX));
    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0)); 
    }

    // There may be a bug here. The EAX will be assigned as BL.
    ibb->add (ST(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDI), 0, s8));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        ibb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));
        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// AB Ia_stosw_Yw_AX
void IA32Interpreter::stosw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("stosw\n");

    op_size = WORD;
    dtype = s32;

    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (USE(IA32ProcessorState::EAX));
    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0)); 
    }

    ibb->add (ST(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDI), 0, s16));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 2, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        ibb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));


        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// AB Ia_stosd_Yd_EAX
void IA32Interpreter::stosd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("stosd\n");
    op_size = WORD;
    dtype = s32;

    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (USE(IA32ProcessorState::EAX));
    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0)); 
    }

    ibb->add (ST(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDI), 0, s32));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 4, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        ibb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

//CD Ia_int_Ib
void IA32Interpreter::i_int(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("i_int\n");
    ibb->add (SYSCALL);
}

//CC Ia_int_Ib
void IA32Interpreter::int3(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    ibb->add (HALT(op->op1.imm-1));
}

//68 Ia_pushl_Id
//6A Ia_pushl_sIb
void IA32Interpreter::i_pushl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_pushl\n");
    // The PUSH ESP instruction pushes the value of the ESP register 
    // as it existed before the instruction was executed
    ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));		// t1 = R[%esp]
    //ibb->add (IA32LI(4, TEMPREG1));						// t2 = 4
    //ibb->add (IA32SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));// t1 = t1 - t2
    ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));// t1 = t1 - t2
    ibb->add (IA32LI(op->op1.imm, TEMPREG1));				// t3 = rA
    ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::ESP), 0, s32));	// M[t1] = t3
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));		// R[%esp] = t1
}

//E8 Ia_call_Jd
void IA32Interpreter::i_call(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_call\n");
    ibb->add (IA32LI((MemAddr)op->op2.imm, TEMPREG2));			// t1 = next
    ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));		// t2 = R[%esp]
    //ibb->add (IA32LI(4, TEMPREG1));						// t3 = 4
    //ibb->add (IA32SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));// t2 = t2 - t3
    ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));// t2 = t2 - t3
    ibb->add (ST(TEMPREG2, VREG(IA32ProcessorState::ESP), 0, s32));	// M[t2] = t1
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));		// R[%esp] = t2
    //ibb->add (JMP(0, op->op1.imm));					// JMP (dest)0
    insn->ilen = op->op1.imm - curNext;
}

// 99 Ia_cdq
void IA32Interpreter::cdq(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("cdq\n");
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (CMP(LT, VREG(IA32ProcessorState::EAX), 0, TEMPREG1));
    ibb->add (IA32SUB(0, TEMPREG1, VREG(IA32ProcessorState::EDX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
}

// 98 Ia_cwde
void IA32Interpreter::cwtl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("cwtl\n");
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (SEXT(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EAX), b16));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//FF /2 Ia_call_Ed
void IA32Interpreter::rorm_call(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_call\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI((MemAddr)op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
        ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::ESP), 0, s32));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (JMP(VREG(insn->rm), 0));
    }
    else
    {
        ibb->add (IA32LI((MemAddr)op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
        ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::ESP), 0, s32));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));

        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (JMP(TEMPREG1, 0));
    }
}

// checkpoint

//8B Ia_movl_Gd_Ed
void IA32Interpreter::r_rorm_movl8b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movl8b\n");
	if (insn->mod == 3)
	{
		ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		ibb->add (IA32MOV(VREG(insn->rm), VREG(op->op1.reg)));
		ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
		XTRegNum t = resolveModRM(insn,op,bb);
		ibb->add (LD(t, 0, VREG(op->op1.reg), s32));
		ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
}

void IA32Interpreter::r_rorm_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movw\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (ZEXT(VREG(insn->rm), TEMPREG1, b16));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// D3 /0 Ia_roll_Ed_CL
void IA32Interpreter::cl_roll(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("cl_roll\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32LI(0x1f, TEMPREG1));
        ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));

        ibb->add (CALL((Word)(&crossbit::set_flags_roll), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32SLL(VREG(insn->rm), TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(32, TEMPREG3));
        ibb->add (IA32SUB(TEMPREG3, TEMPREG1, TEMPREG3));
        ibb->add (IA32SRL(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);

        ibb->add (LD(t, 0, TEMPREG2, s32));

        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32LI(0x1f, TEMPREG1));
        ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));

        ibb->add (CALL((Word)(&crossbit::set_flags_roll), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG3));
        ibb->add (IA32LI(32, TEMPREG4));
        ibb->add (IA32SUB(TEMPREG4, TEMPREG1, TEMPREG4));
        ibb->add (IA32SRL(TEMPREG2, TEMPREG4, TEMPREG2));
        ibb->add (IA32OR(TEMPREG2, TEMPREG3, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

// D1 /0 Ia_roll_Eb_I1
void IA32Interpreter::rorm_roll(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_roll\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_roll), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32SLL(VREG(insn->rm), TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(31, TEMPREG3));
        ibb->add (IA32SRL(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);

        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32LI(0x1, TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_roll), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG3));
        ibb->add (IA32LI(31, TEMPREG4));
        ibb->add (IA32SRL(TEMPREG2, TEMPREG4, TEMPREG2));
        ibb->add (IA32OR(TEMPREG2, TEMPREG3, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

// C1 /1 ib Ia_rorl_Ed_Ib
void IA32Interpreter::rorm_i_rorl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_rorl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32LI((op->op2.imm & 0x1f), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_rorl), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(32, TEMPREG3));
        ibb->add (IA32SUB(TEMPREG3, TEMPREG1, TEMPREG3));
        ibb->add (IA32SLL(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32LI((op->op2.imm & 0x1f), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_rorl), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG3));
        ibb->add (IA32LI(32, TEMPREG4));
        ibb->add (IA32SUB(TEMPREG4, TEMPREG1, TEMPREG4));
        ibb->add (IA32SLL(TEMPREG2, TEMPREG4, TEMPREG2));
        ibb->add (IA32OR(TEMPREG2, TEMPREG3, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

// C1 /1 Ia_rorw_Ew_Ib
void IA32Interpreter::rorm_i_rorw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_rorw\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32LI((op->op2.imm & 0xf), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_rorw), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(16, TEMPREG3));
        ibb->add (IA32SUB(TEMPREG3, TEMPREG1, TEMPREG3));
        ibb->add (IA32SLL(VREG(insn->rm), TEMPREG3, TEMPREG1));
        ibb->add (IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (IA32LI((op->op2.imm & 0xf), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_rorw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG3));
        ibb->add (IA32LI(16, TEMPREG4));
        ibb->add (IA32SUB(TEMPREG4, TEMPREG1, TEMPREG4));
        ibb->add (IA32SLL(TEMPREG2, TEMPREG4, TEMPREG2));
        ibb->add (IA32OR(TEMPREG2, TEMPREG3, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

//C2 Ia_ret_Ew
void IA32Interpreter::i_ret(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_ret\n");
    ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    ibb->add (LD(VREG(IA32ProcessorState::ESP), 0, TEMPREG1, s32));
    //ibb->add (IA32LI((op->op1.imm + 4), TEMPREG2));
    //ibb->add (IA32ADD(VREG(IA32ProcessorState::ESP), TEMPREG2, VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESP), (op->op1.imm + 4), VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));

    ibb->add (JMP(TEMPREG1, 0));
}

//C3 Ia_ret
void IA32Interpreter::ret(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("ret\n");
    ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    ibb->add (LD(VREG(IA32ProcessorState::ESP), 0, TEMPREG1, s32));
    //ibb->add (IA32LI(4, TEMPREG2));
    //ibb->add (IA32ADD(VREG(IA32ProcessorState::ESP), TEMPREG2, VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    ibb->add (JMP(TEMPREG1, 0));
}

//added by zhengjuyu
//modified by Chuchao
//80 /2 Ia_adcb_Eb_Ib
//TODO
void IA32Interpreter::rorm_i_adcb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_adcb80\n");
    XTRegNum t = resolveModRM(insn, op, bb);
    ibb->add (IA32LI(op->op2.imm, t2));
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, t3));

    }
    else
    {
        printf("adcb_ib\n");
        exit(0);
    }
    printf("adcb_ib\n");
    exit(0);
}

//added by zhengjuyu
//
void IA32Interpreter::adcl_id(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("adcl_id\n");
    XTRegNum t = resolveModRM(insn, op, bb);
    ibb->add (IA32LI(op->op2.imm, t2));
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, t3));

    }
    else
    {
        printf("adcl_id\n");
        exit(0);
    }
    printf("adcl_id\n");
    exit(0);
}

// A bug here, the flags may be wrong!
// 83 /2 ib Ia_adcl_Ed_sIb
void IA32Interpreter::adcl_sib(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("adcl_sib\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));

		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, VREG(insn->rm), TEMPREG1, TEMPREG2));
			SET_FLAGS_ADCL(VREG(insn->rm), TEMPREG1, TEMPREG2);
		}

        ibb->add (IA32ADD(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));

        ibb->add (IA32ADD(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG3, s32));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, TEMPREG3, TEMPREG1, TEMPREG2));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_ADCL(TEMPREG3, TEMPREG1, TEMPREG2);
		}

        ibb->add (IA32ADD(TEMPREG3, TEMPREG1, TEMPREG3));
        ibb->add (IA32ADD(TEMPREG3, TEMPREG2, TEMPREG3));
        ibb->add (ST(TEMPREG3, t, 0, s32));
    }
}

// 0F C1 Ia_xaddl_Ed_Gd
void IA32Interpreter::rorm_r_xaddl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_xaddl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op2.reg), VREG(insn->rm)));
		SET_FLAGS_ADDL( VREG(op->op2.reg), VREG(insn->rm) )

        ibb->add (IA32ADD(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
        ibb->add (IA32MOV(VREG(insn->rm), VREG(op->op2.reg)));
        ibb->add (IA32MOV(TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        ibb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        //ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op2.reg), TEMPREG1));
		SET_FLAGS_ADDL( VREG(op->op2.reg), TEMPREG1 )

        ibb->add (IA32ADD(VREG(op->op2.reg), TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
        ibb->add (IA32MOV(TEMPREG1, VREG(op->op2.reg)));
        ibb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
    }
}

//01 /r Ia_addl_Ed_Gd
void IA32Interpreter::rorm_r_addl01(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_addl01\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op2.reg), VREG(insn->rm)));
			SET_FLAGS_ADDL( VREG(op->op2.reg), VREG(insn->rm) );
		}

        ibb->add (IA32ADD(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, TEMPREG1, VREG(op->op2.reg)));
			SET_FLAGS_ADDL( TEMPREG1, VREG(op->op2.reg) );
		}

        ibb->add (IA32ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s32));
    }
}

//11 /r Ia_adcl_Ed_Gd
void IA32Interpreter::rorm_r_adcl11(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_adcl11\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_ADCL(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1);
		}

        ibb->add (IA32ADD(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32ADD(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, TEMPREG2, VREG(op->op2.reg), TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_ADCL(TEMPREG2, VREG(op->op2.reg), TEMPREG1);
		}

        ibb->add (IA32ADD(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32ADD(TEMPREG2, VREG(op->op2.reg), TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

//03 /r Ia_addl_Gd_Ed
void IA32Interpreter::r_rorm_addl03(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_addl03\n");
    if(mode_ == NORMAL)
    {
        if (insn->mod == 3)
        {
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            //ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op1.reg), VREG(insn->rm)));
			SET_FLAGS_ADDL( VREG(op->op1.reg), VREG(insn->rm) )

            ibb->add (IA32ADD(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s32));
            //ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op1.reg), TEMPREG1));
			SET_FLAGS_ADDL( VREG(op->op1.reg), TEMPREG1 )

            ibb->add (IA32ADD(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
    else if(mode_ == PTX)
    {
        if (insn->mod == 3)
        {
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

            ibb->add (IA32ADD(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s32));

            ibb->add (IA32ADD(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
    else
    {
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
    }
}

// 04 ib Ia_addb_AL_Ib
void IA32Interpreter::AL_i_addb04(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("AL_i_addb04\n");

    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));

    ibb->add (IA32ADD(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    ibb->add (IA32LI(0xffffff00, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI(0xff, TEMPREG2));
    ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

// 2C ib Ia_subb_AL_Ib
void IA32Interpreter::AL_i_subb2c(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("AL_i_subb2c\n");

    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
	// added by zhangyichao, 2010-4-15
	SET_FLAGS_SUBB(VREG(IA32ProcessorState::EAX), TEMPREG1)

    ibb->add (IA32SUB(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    ibb->add (IA32LI(0xffffff00, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI(0xff, TEMPREG2));
    ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}


// 00 /r Ia_addb_Eb_Gb
void IA32Interpreter::rorm_r_addb00(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_addb00\n");
    if (insn->mod == 3)
    {
        if (op->op2.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(insn->rm), VREG(op->op2.reg)));

                ibb->add (IA32ADD(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
                ibb->add (IA32LI(0xff, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -= 4;

                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, VREG(op->op2.reg)));

                ibb->add (IA32ADD(TEMPREG2, VREG(op->op2.reg), TEMPREG1));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xff00, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
        else
        {
            op->op2.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(insn->rm), TEMPREG3));

                ibb->add (IA32ADD(VREG(insn->rm), TEMPREG3, TEMPREG1));
                ibb->add (IA32LI(0xff, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -= 4;

                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, TEMPREG3));

                ibb->add (IA32ADD(TEMPREG2, TEMPREG3, TEMPREG1));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xff00, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));

        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG1, VREG(op->op2.reg)));

            ibb->add (IA32ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
        else
        {
            op->op2.reg -= 4;
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
            ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG1, TEMPREG3));

            ibb->add (IA32ADD(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
    }
}

// 80 Ia_addb_Eb_Ib
void IA32Interpreter::rorm_i_addb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_addb80\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(insn->rm), TEMPREG1));

            ibb->add (IA32ADD(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (IA32LI(0xff, TEMPREG1));
            ibb->add (IA32AND(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
            ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG3, TEMPREG1));

            ibb->add (IA32ADD(TEMPREG3, TEMPREG1, TEMPREG3));
            ibb->add (IA32SLL(TEMPREG3, TEMPREG2, TEMPREG3));
            ibb->add (IA32LI(0xff00, TEMPREG1));
            ibb->add (IA32AND(TEMPREG3, TEMPREG1, TEMPREG3));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32ADD(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s8));
    }
}

//02 Ia_addb_Gb_Eb
void IA32Interpreter::r_rorm_addb02(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_addb02\n");
    if (insn->mod == 3)
    {
        if (op->op1.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(op->op1.reg), VREG(insn->rm)));

                ibb->add (IA32ADD(VREG(op->op1.reg), VREG(insn->rm), TEMPREG1));
                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -= 4;

                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(op->op1.reg), TEMPREG2));

                ibb->add (IA32ADD(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
        else
        {
            op->op1.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG3));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG3, VREG(insn->rm)));

                ibb->add (IA32ADD(TEMPREG3, VREG(insn->rm), TEMPREG3));
                ibb->add (ZEXT(TEMPREG3, TEMPREG3, b8));
                ibb->add (IA32SLL(TEMPREG3, TEMPREG1, TEMPREG3));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG3, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -= 4;

                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG3));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG3, TEMPREG2));

                ibb->add (IA32ADD(TEMPREG3, TEMPREG2, TEMPREG3));
                ibb->add (ZEXT(TEMPREG3, TEMPREG3, b8));
                ibb->add (IA32SLL(TEMPREG3, TEMPREG1, TEMPREG3));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG3, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));

        if (op->op1.reg < 4)
        {
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(op->op1.reg), TEMPREG1));

            ibb->add (IA32ADD(VREG(op->op1.reg), TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            op->op1.reg -=4;

            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG3, TEMPREG2));
            ibb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, TEMPREG1));

            ibb->add (IA32ADD(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG3, TEMPREG2));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
}

//03 /r Ia_addw_Ew_Gw
void IA32Interpreter::rorm_r_addw01(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_addw01\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(op->op2.reg), VREG(insn->rm)));

        ibb->add (IA32ADD(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (CALL((Word)(&crossbit::set_flags_addw), 2, TEMPREG1, VREG(op->op2.reg)));
        ibb->add (IA32ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s16));
    }
}

//03 /r Ia_addw_Gw_Ew
void IA32Interpreter::r_rorm_addw03(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_addw03\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(op->op1.reg), VREG(insn->rm)));

        ibb->add (IA32ADD(VREG(op->op1.reg), VREG(insn->rm), TEMPREG2));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(op->op1.reg), TEMPREG1));

        ibb->add (IA32ADD(TEMPREG1, VREG(op->op1.reg), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//05 Ia_addl_EAX_Id
void IA32Interpreter::EAX_i_addl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("EAX_i_addl\n");
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI (op->op2.imm, TEMPREG1));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
		SET_FLAGS_ADDL( VREG(IA32ProcessorState::EAX), TEMPREG1 );
	}

    ibb->add (IA32ADD(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//81 /0 Ia_addl_Ed_Id
void IA32Interpreter::rorm_i_addl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_addl81\n");
    rorm_i_addl83(insn, op, bb);
}

//83 /0 Ia_addl_Ed_sIb
void IA32Interpreter::rorm_i_addl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_addl83\n");
	if(mode_ == NORMAL)
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
			//ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2,VREG(insn->rm), TEMPREG1));
			SET_FLAGS_ADDL( VREG(insn->rm), TEMPREG1 );

			ibb->add (IA32ADD(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
			ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
			ibb->add (LD(t, 0, TEMPREG2, s32));
			//ibb->add (CALL((Word)(&crossbit::set_flags_addl), 2, TEMPREG2, TEMPREG1));
			SET_FLAGS_ADDL( TEMPREG2, TEMPREG1 );

			ibb->add (IA32ADD(TEMPREG2, TEMPREG1, TEMPREG2));
			ibb->add (ST(TEMPREG2, t, 0, s32));
		}
	}
	else if(mode_ == PTX)
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

			ibb->add (IA32ADD(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
			ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
			ibb->add (LD(t, 0, TEMPREG2, s32));

			ibb->add (IA32ADD(TEMPREG2, TEMPREG1, TEMPREG2));
			ibb->add (ST(TEMPREG2, t, 0, s32));
		}
	}
}

//83 /0 Ia_addl_Ed_sIb
void IA32Interpreter::rorm_i_addw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_addw83\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32ADD(TEMPREG1, VREG(insn->rm), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (CALL((Word)(&crossbit::set_flags_addw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32ADD(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

//58-5F Ia_popl_ERX
void IA32Interpreter::r_popl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_popl\n");
    ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    ibb->add (LD(VREG(IA32ProcessorState::ESP), 0, VREG(op->op1.reg), s32));
    ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg ));
    //ibb->add (IA32LI(4, TEMPREG1));
    //ibb->add (IA32ADD(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
}

//21 /r Ia_andw_Ew_Gw
void IA32Interpreter::rorm_r_andw21(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_andw21\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32AND(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (IA32AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

        ibb->add (ST(TEMPREG1, t, 0, s16));
    }
}

//21 /r Ia_andl_Ed_Gd
void IA32Interpreter::rorm_r_andl21(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_andl21\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32AND(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));
			SET_FLAGS_ANDL( VREG(insn->rm) );
		}

        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG1));
			SET_FLAGS_ANDL( TEMPREG1 );
		}

        ibb->add (ST(TEMPREG1, t, 0, s32));
    }
}

//22 /r Ia_andw_Gd_Ed
void IA32Interpreter::r_rorm_andb22(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_andb22\n");
    //op_size = BYTE;

    if (insn->mod == 3)
    {
        if (op->op1.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32AND(VREG(op->op1.reg), VREG(insn->rm), TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -=4;
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG3, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
        else
        {
            op->op1.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -=4;

                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));

        if (op->op1.reg < 4)
        {
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32AND(TEMPREG1, VREG(op->op1.reg), TEMPREG1));
            //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
			SET_FLAGS_ANDB( TEMPREG1 )

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            op->op1.reg -= 4;

            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG3));
            ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
            //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
			SET_FLAGS_ANDB( TEMPREG1 )

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
}

//23 /r Ia_andl_Gd_Ed
void IA32Interpreter::r_rorm_andl23(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_andl23\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32AND(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));
			SET_FLAGS_ANDL( VREG(op->op1.reg) );
		}

        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));
			SET_FLAGS_ANDL( VREG(op->op1.reg) );
		}

        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 20 Ia_andb_Eb_Gb
void IA32Interpreter::rorm_r_andb20(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_andb20\n");
    if (insn->mod == 3)
    {
        if (op->op2.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32AND(VREG(op->op2.reg), TEMPREG3, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
        else
        {
            op->op2.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -=4;

                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            ibb->add (IA32AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
            //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
			SET_FLAGS_ANDB( TEMPREG1 )

            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
        else
        {
            op->op2.reg -= 4;

            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
            //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
			SET_FLAGS_ANDB( TEMPREG1 )

            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
    }
    /*
       op_size = BYTE;
       if (insn->mod == 3)
       {
       ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
       ibb->add (IA32AND(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
       ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(insn->rm)));

       ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
       }
       else
       {
       XTRegNum t = resolveModRM(insn,op,bb);
       ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       ibb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
       ibb->add (IA32AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
       ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

       ibb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
       }
       */
}

// 24 ib Ia_andb_AL_Ib
void IA32Interpreter::AL_i_andb24(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("AL_i_andb24\n");
    //op_size = BYTE;

    ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
	SET_FLAGS_ANDB( TEMPREG1 )

    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
    ibb->add (IA32LI(0xffffff00, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//80 /4 Ia_andb_Eb_Ib
void IA32Interpreter::rorm_i_andb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_andb80\n");
    //op_size = BYTE;

    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 );
			}

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
            ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 );
			}

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (IA32AND(TEMPREG2, TEMPREG1, TEMPREG2));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG2));
			SET_FLAGS_ANDB( TEMPREG2 );
		}

        ibb->add (ST(TEMPREG2, t, 0, s8));
    }
}

//81 /4 Ia_andw_Ew_Iw
void IA32Interpreter::rorm_i_andw81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_andw81\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (IA32AND(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG2));

        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

//81 /4 Ia_andl_Ed_Id
void IA32Interpreter::rorm_i_andl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_andl81\n");
    rorm_i_andl83(insn, op, bb);
}

//83 /4 Ia_andl_Ed_sIb
void IA32Interpreter::rorm_i_andl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_andl83\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));
			SET_FLAGS_ANDL( VREG(insn->rm) );
		}

        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32AND(TEMPREG2, TEMPREG1, TEMPREG2));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG2));
			SET_FLAGS_ANDL( TEMPREG2 );
		}

        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

//28 /r Ia_subb_Eb_Gb
void IA32Interpreter::rorm_r_subb28(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_subb28\n");
    if (insn->mod == 3)
    {
        if (op->op2.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), VREG(op->op2.reg)));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(VREG(insn->rm), VREG(op->op2.reg))

                ibb->add (IA32SUB(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
                ibb->add (IA32LI(0xff, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -= 4;

                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, VREG(op->op2.reg)));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(TEMPREG2, VREG(op->op2.reg))

                ibb->add (IA32SUB(TEMPREG2, VREG(op->op2.reg), TEMPREG1));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xff00, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
        else
        {
            op->op2.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                //ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG3));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(VREG(insn->rm), TEMPREG1)

                ibb->add (IA32SUB(VREG(insn->rm), TEMPREG3, TEMPREG1));
                ibb->add (IA32LI(0xff, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -= 4;

                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG1));
                //ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                //ibb->add (IA32LI(0x8, TEMPREG1));
                //ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
                ibb->add (IA32LI(0x8, TEMPREG3));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG3, TEMPREG2));
                //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG3));
				// added by zhangyichao, 2010-4-15
				SET_FLAGS_SUBB(TEMPREG2, TEMPREG1)

                //ibb->add (IA32SUB(TEMPREG2, TEMPREG3, TEMPREG1));
                ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG1));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xff00, TEMPREG2));
                ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));

        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, VREG(op->op2.reg)));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(TEMPREG1, VREG(op->op2.reg))

            ibb->add (IA32SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
        else
        {
            op->op2.reg -= 4;
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            //ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG2));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, TEMPREG3));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(TEMPREG1, TEMPREG2)

            //ibb->add (IA32SUB(TEMPREG1, TEMPREG3, TEMPREG1));
            ibb->add (IA32SUB(TEMPREG1, TEMPREG2, TEMPREG1));
            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
    }

    /*
       op_size = BYTE;

       if (insn->mod == 3)
       {
       ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
       ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), VREG(op->op2.reg)));

       ibb->add (IA32SUB(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
       ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
       }
       else
       {
       XTRegNum t = resolveModRM(insn,op,bb);
       ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       ibb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
       ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, VREG(op->op2.reg)));

       ibb->add (IA32SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
       ibb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
       }
       */
}

// 28 /r Ia_subb_Eb_Ib
void IA32Interpreter::rorm_i_subb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_subb80\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(VREG(insn->rm), TEMPREG1)

            ibb->add (IA32SUB(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (IA32LI(0xff, TEMPREG1));
            ibb->add (IA32AND(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG2));
            //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG3, TEMPREG1));
			// added by zhangyichao, 2010-4-15
			SET_FLAGS_SUBB(TEMPREG2, TEMPREG1)

            ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG3));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SLL(TEMPREG3, TEMPREG2, TEMPREG3));
            ibb->add (IA32LI(0xff00, TEMPREG1));
            ibb->add (IA32AND(TEMPREG3, TEMPREG1, TEMPREG3));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));
		// added by zhangyichao, 2010-4-15
		SET_FLAGS_SUBB(TEMPREG2, TEMPREG1)

        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s8));
    }

    /*
       op_size = BYTE;
       if (insn->mod == 3)
       {
       ibb->add (IA32LI(op->op2.imm, TEMPREG1));
       ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
       ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG1));

       ibb->add (IA32SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
       ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
       }
       else
       {
       XTRegNum t = resolveModRM(insn,op,bb);
       ibb->add (IA32LI(op->op2.imm, TEMPREG1));
       ibb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
       ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));

       ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
       ibb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
       }
       */
}

//29 /r Ia_subl_Ed_Gd
void IA32Interpreter::rorm_r_subl29(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_subl29\n");
	if(mode_ == NORMAL)
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), VREG(op->op2.reg)));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(VREG(insn->rm), VREG(op->op2.reg));

			ibb->add (IA32SUB(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
			ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
			ibb->add (LD(t, 0, TEMPREG1, s32));
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG1, VREG(op->op2.reg)));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(TEMPREG1, VREG(op->op2.reg));

			ibb->add (IA32SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
			ibb->add (ST(TEMPREG1, t, 0, s32));
		}
	}
	else if(mode_ == PTX)
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

			ibb->add (IA32SUB(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
			ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
			ibb->add (LD(t, 0, TEMPREG1, s32));

			ibb->add (IA32SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
			ibb->add (ST(TEMPREG1, t, 0, s32));
		}
	}
	else
	{
		UTIL::XTLOG("Unknown interp mode!\n");
		exit(0);
	}
}

//2B /r Ia_subl_Gd_Ed
void IA32Interpreter::r_rorm_subl2b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_subl2b\n");
	if( mode_ == NORMAL )
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), VREG(insn->rm)));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(VREG(op->op1.reg), VREG(insn->rm));

			ibb->add (IA32SUB(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
			ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
			ibb->add (LD(t, 0, TEMPREG1, s32));
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(VREG(op->op1.reg), TEMPREG1);

			ibb->add (IA32SUB(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
			ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
		}
	}
	else if( mode_ == PTX )
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

			ibb->add (IA32SUB(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
			ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
			ibb->add (LD(t, 0, TEMPREG1, s32));

			ibb->add (IA32SUB(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
			ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
		}
	}
	else
	{
		UTIL::XTLOG("Unknown interp mode!\n");
		exit(0);
	}
}

// 29 /r Ia_subw_Ew_Gw
void IA32Interpreter::rorm_r_subw29(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_subw29\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), VREG(op->op2.reg)));
		SET_FLAGS_SUBW( VREG(insn->rm), VREG(op->op2.reg) );

        ibb->add (IA32SUB(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG1, VREG(op->op2.reg)));
		SET_FLAGS_SUBW( TEMPREG1, VREG(op->op2.reg) );

        ibb->add (IA32SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s16));
    }
}

//2B /r Ia_subl_Gw_Ew
void IA32Interpreter::r_rorm_subw2b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_subw2b\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), VREG(insn->rm)));
		SET_FLAGS_SUBW( VREG(op->op1.reg), VREG(insn->rm) );

        ibb->add (IA32SUB(VREG(op->op1.reg), VREG(insn->rm), TEMPREG2));		
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), TEMPREG1));
		SET_FLAGS_SUBW( VREG(op->op1.reg), TEMPREG1 );

        ibb->add (IA32SUB(VREG(op->op1.reg), TEMPREG1, TEMPREG2));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 81 /5 Ia_subl_Ed_Id
void IA32Interpreter::rorm_i_subl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_subl81\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(VREG(insn->rm), TEMPREG1);
		}
        ibb->add (IA32SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(TEMPREG2, TEMPREG1);
		}
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

//83 /5 Ia_subl_Ed_sIb
void IA32Interpreter::rorm_i_subl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_subl83\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(VREG(insn->rm), TEMPREG1);
		}

        ibb->add (IA32SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(TEMPREG2, TEMPREG1);
		}

        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

// 83 /5 ib Ia_subw_Ew_sIb
void IA32Interpreter::rorm_i_subw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_subw83\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), TEMPREG1));
		SET_FLAGS_SUBW( VREG(insn->rm), TEMPREG1 );

        ibb->add (IA32SUB(VREG(insn->rm), TEMPREG1, TEMPREG2));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG2, TEMPREG1));
		SET_FLAGS_SUBW( TEMPREG2, TEMPREG1 );

        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

//2D Ia_subl_EAX_Id
void IA32Interpreter::EAX_i_subl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("EAX_i_subl\n");
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI (op->op2.imm, TEMPREG1));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(IA32ProcessorState::EAX), TEMPREG1);
	}

    ibb->add (IA32SUB(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//50-57 Ia_pushl_ERX
void IA32Interpreter::r_pushl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_pushl\n");
    if ( (op->op1.reg) == IA32ProcessorState::ESP)
    {
        ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32MOV(VREG(IA32ProcessorState::ESP), TEMPREG1));
        //ibb->add (IA32LI(4, TEMPREG1));
        //ibb->add (IA32SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
        ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::ESP), 0, s32));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
    else
    {
        ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
        //ibb->add (IA32LI(4, TEMPREG1));
        //ibb->add (IA32SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (ST(VREG(op->op1.reg), VREG(IA32ProcessorState::ESP), 0, s32));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
}

//FF /6 Ia_pushl_Ed
void IA32Interpreter::rorm_pushl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_pushl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
        //ibb->add (IA32LI(4, TEMPREG1));
        //ibb->add (IA32SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (ST(VREG(insn->rm), VREG(IA32ProcessorState::ESP), 0, s32));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
    else
    {	
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
        //ibb->add (IA32LI(4, TEMPREG1));
        //ibb->add (IA32SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));

        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::ESP), 0, s32));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
}

//B8-BF Ia_movl_ERX_Id
void IA32Interpreter::r_i_movl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_i_movl\n");
    ibb->add (IA32LI ((Word)op->op2.imm, VREG(op->op1.reg)));
    ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

void IA32Interpreter::r_i_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_i_movw\n");
    ibb->add (IA32LI ((Word)op->op2.imm, TEMPREG1));
    ibb->add (IA32LI(0xffff0000, TEMPREG2));
    ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

// There may be a bug here, the flags may be wrong!
//83 /3 Ia_sbbl_Ed_sIb
void IA32Interpreter::rorm_i_sbbl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_sbbl83\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
        ibb->add (IA32ADD(TEMPREG1, TEMPREG2, TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(VREG(insn->rm), TEMPREG1);
		}

        ibb->add (IA32SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
		ibb->add (IA32LI(op->op2.imm, TEMPREG1));
		ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
        ibb->add (IA32ADD(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(TEMPREG2, TEMPREG1);
		}
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
		/*	old version, 2010-4-14
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG3, s32));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
        ibb->add (IA32ADD(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG3, TEMPREG1));

        ibb->add (IA32SUB(TEMPREG3, TEMPREG1, TEMPREG3));
        ibb->add (ST(TEMPREG3, t, 0, s32));
		*/
    }
}

//19 Ia_sbbl_Ed_Gd
void IA32Interpreter::rorm_r_sbbl19(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_sbbl19\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(VREG(insn->rm), TEMPREG1);
		}

        ibb->add (IA32SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
			// added by zhangyichao, 2010-4-14
			SET_FLAGS_SUBL(TEMPREG2, TEMPREG1);
		}

        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

// 1B /r Ia_sbbl_Gd_Ed
void IA32Interpreter::r_rorm_sbbl1b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_sbbl1b\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32ADD(TEMPREG1, VREG(insn->rm), TEMPREG1));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(op->op1.reg), TEMPREG1)

        ibb->add (IA32SUB(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32ADD(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        //ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));
		// added by zhangyichao, 2010-4-14
		SET_FLAGS_SUBL(VREG(op->op1.reg), TEMPREG1)

        ibb->add (IA32SUB(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// A bug here, the segOver isn't processed.
//A1 Ia_movl_EAX_Od
void IA32Interpreter::EAX_mo_movl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("EAX_mo_movl\n");
    if(segOver)
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, t2, s32));
        ibb->add (IA32PUT(t2,IA32ProcessorState::EAX));	
    }
    else
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(TEMPREG1, 0, VREG(IA32ProcessorState::EAX), s32));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    }
}

//A3 Ia_movl_Od_EAX
void IA32Interpreter::mo_EAX_movl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("mo_EAX_movl\n");
    if(segOver)
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(IA32ProcessorState::EAX, t2));
        ibb->add (ST(t2, t, 0, s32));
    }
    else
    {
        ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32LI(op->op1.imm, TEMPREG1));
        ibb->add (ST(VREG(IA32ProcessorState::EAX), TEMPREG1, 0, s32));
    }
}

//75 Ia_jne_Jb
void IA32Interpreter::i_jneb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jneb\n");
    i_jned(insn,op,bb);
}

//3D /id Ia_cmpl_EAX_Id
void IA32Interpreter::EAX_i_cmpl3d(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("EAX_i_cmpl3d\n");
    ibb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add(IA32LI(op->op2.imm, TEMPREG1));
    //ibb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
	// added by zhangyichao, 2010-4-14
	SET_FLAGS_SUBL(VREG(IA32ProcessorState::EAX), TEMPREG1)
}

//3C /ib Ia_cmpb_AL_Ib
void IA32Interpreter::AL_i_cmpb3c(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{	
    if(ptx_msg) printf("AL_i_cmpb3c\n");
    //op_size = BYTE;
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
		// added by zhangyichao, 2010-4-15
		SET_FLAGS_SUBB(VREG(IA32ProcessorState::EAX), TEMPREG1);
	}
}

//0F 84 Ia_jz_Jd
void IA32Interpreter::i_jzd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jzd\n");
    i_jzb(insn,op,bb);
}

//84 /r Ia_testl_Eb_Gb
void IA32Interpreter::rorm_r_testb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_testb\n");
    if (insn->mod == 3)
    {
        if (op->op2.reg < 4)
        {
            if (insn->rm < 4)
            {
                if (op->op2.reg == insn->rm)
                {
                    ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
					if( mode_ == NORMAL )
					{
						//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, VREG(op->op2.reg)));
						SET_FLAGS_TESTB( VREG(op->op2.reg) );
					}
				}
                else
                {
                    ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                    ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                    ibb->add (IA32AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
					if( mode_ == NORMAL )
					{
						//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
						SET_FLAGS_TESTB( TEMPREG1 ); 
					}
				}
            }
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32AND(VREG(op->op2.reg), TEMPREG3, TEMPREG1));
				if( mode_ == NORMAL )
				{
					//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
					SET_FLAGS_TESTB( TEMPREG1 );
				}
			}
        }
        else
        {
            op->op2.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
				if( mode_ == NORMAL )
				{
					//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
					SET_FLAGS_TESTB( TEMPREG1 );
				}
            }
            else
            {
                insn->rm -=4;

                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
				if( mode_ == NORMAL )
				{
					//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
					SET_FLAGS_TESTB( TEMPREG1 );
				}
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            ibb->add (IA32AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
				SET_FLAGS_TESTB( TEMPREG1 );
			}
		}
        else
        {
            op->op2.reg -= 4;

            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            ibb->add (IA32AND(TEMPREG1, TEMPREG3, TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
				SET_FLAGS_TESTB( TEMPREG1 );
			}
        }
    }

}

//0F B6 Ia_movzbl_Gd_Eb
void IA32Interpreter::r_rorm_movzbl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movzbl\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (ZEXT(VREG(insn->rm), VREG(op->op1.reg), b8));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, VREG(op->op1.reg), b8));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (LD(t, 0, TEMPREG1, s8));
        ibb->add (ZEXT(TEMPREG1, VREG(op->op1.reg), b8));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

}

//0F B6 Ia_movzbl_Gd_Eb
void IA32Interpreter::r_rorm_movzbw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movzbw\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (ZEXT(VREG(insn->rm), TEMPREG2, b8));

            //op_size = HALFWORD;
            ibb->add (IA32LI(0xffff0000, TEMPREG1));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));

            //op_size = HALFWORD;
            ibb->add (IA32LI(0xffff0000, TEMPREG1));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));

        //op_size = HALFWORD;
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//0F B7 Ia_movzwl_Gd_Ew
void IA32Interpreter::r_rorm_movzwl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movzwl\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (ZEXT(VREG(insn->rm), VREG(op->op1.reg), b16));

        op_size = WORD;
        dtype = s32;
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (ZEXT(TEMPREG1, VREG(op->op1.reg), b16));

        op_size = WORD;
        dtype = s32;
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//0F BF Ia_movswl_Gd_Ew
void IA32Interpreter::r_rorm_movswl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movswl\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (SEXT(VREG(insn->rm), VREG(op->op1.reg), b16));

        op_size = WORD;
        dtype = s32;
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (SEXT(TEMPREG1, VREG(op->op1.reg), b16));

        op_size = WORD;
        dtype = s32;
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//0F BE Ia_movsbl_Gd_Eb
void IA32Interpreter::r_rorm_movsbl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movsbl\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (SEXT(VREG(insn->rm), VREG(op->op1.reg), b8));

            op_size = WORD;
            dtype = s32;
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (SEXT(TEMPREG2, VREG(op->op1.reg), b8));

            op_size = WORD;
            dtype = s32;
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));	
        ibb->add (SEXT(TEMPREG1, VREG(op->op1.reg), b8));

        op_size = WORD;
        dtype = s32;
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

}

// 0F BE /r Ia_movsbw_Gw_Eb
void IA32Interpreter::r_rorm_movsbw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_movsbw\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (SEXT(VREG(insn->rm), TEMPREG2, b8));

            //op_size = HALFWORD;
            ibb->add (IA32LI(0xffff0000, TEMPREG1));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
            ibb->add (SEXT(TEMPREG2, TEMPREG2, b8));

            //op_size = HALFWORD;
            ibb->add (IA32LI(0xffff0000, TEMPREG1));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));	
        ibb->add (SEXT(TEMPREG1, TEMPREG1, b8));

        //op_size = HALFWORD;
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

}

//C7 Ia_movl_Ed_Id
void IA32Interpreter::rorm_i_movlc7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_i_movlc7\n");
	if (insn->mod == 3)
	{
		ibb->add (IA32LI(op->op2.imm, VREG(insn->rm)));
		ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
		XTRegNum t = resolveModRM(insn,op,bb);
		ibb->add (IA32LI(op->op2.imm, TEMPREG1));
		ibb->add (ST(TEMPREG1, t, 0, s32));	
	}
}

//C7 Ia_movl_Ew_Iw
void IA32Interpreter::rorm_i_movwc7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if(ptx_msg) printf("rorm_i_movwc7\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s16));	
    }
}

//76 Ia_jbe_Jb  Note:jbe is the same of jna   (CF==1 or ZF==1)
void IA32Interpreter::i_jbed(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jbed\n");
    i_jbeb(insn,op,bb);
}

//0F 86 Ia_jbe_Jd  Note:jbe is the same of jna   (CF==1 or ZF==1)
void IA32Interpreter::i_jbeb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jbeb\n");
    ibb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    ibb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG2));
    ibb->add(IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));
    ibb->add(BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//77 Ia_jnbe_Jb  Note:jnbe is the same of ja   (CF==0 && ZF==0)
void IA32Interpreter::i_jnbeb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnbeb\n");
    ibb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    ibb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG2));
    ibb->add(IA32OR(TEMPREG1, TEMPREG2, TEMPREG1));
    ibb->add(BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

//0F 87 Ia_jnbe_Jd 
void IA32Interpreter::i_jnbed(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnbed\n");
    i_jnbeb(insn, op, bb);
}

//7D Ia_jnl_Jb  Note:jnl is the same of jge   (OF==SF)
void IA32Interpreter::i_jnlb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnlb\n");
	ibb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
	ibb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
	ibb->add(BRANCH(EQ, TEMPREG1, TEMPREG2, 0, op->op1.imm));
}

// 0f 8d
void IA32Interpreter::i_jnld(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnld\n");

	ibb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
	ibb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
	ibb->add(BRANCH(EQ, TEMPREG1, TEMPREG2, 0, op->op1.imm));	
}

//7F Ia_jnle_Jb  Note:jnle is the same of jg   (OF==SF && ZF==0)
void IA32Interpreter::i_jnleb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnleb\n");
    ibb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
    ibb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
    ibb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG3));
    ibb->add(CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG4));
    ibb->add(BRANCH(LT, TEMPREG3, TEMPREG4, 0, op->op1.imm));	
}

// 0f 8f
void IA32Interpreter::i_jnled(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnled\n");
    ibb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
    ibb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
    ibb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG3));
    ibb->add(CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG4));
    ibb->add(BRANCH(LT, TEMPREG3, TEMPREG4, 0, op->op1.imm));
}

//0F 95 Ia_setnz_Eb
void IA32Interpreter::rorm_setnz(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_setnz\n");
    ibb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG1));

    //op_size = BYTE;
    ibb->add(CMP(EQ, TEMPREG1, 0, TEMPREG2));
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32LI(0x8, TEMPREG1));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (ST(TEMPREG2, t, 0, s8));
    }
}

// 0D id Ia_orl_EAX_id
void IA32Interpreter::EAX_i_orl0d(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("EAX_i_orl0d\n");
    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(IA32ProcessorState::EAX)));
		SET_FLAGS_ANDL( VREG(IA32ProcessorState::EAX) );
	}

    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//09 /r Ia_orl_Ed_Gd
void IA32Interpreter::rorm_r_orl09(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_orl09\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));
			SET_FLAGS_ANDL( VREG(insn->rm) );
		}

        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32OR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG1));
			SET_FLAGS_ANDL( TEMPREG1 );
		}

        ibb->add (ST(TEMPREG1, t, 0, s32));
    }
}

//09 /r Ia_orw_Ew_Gw
void IA32Interpreter::rorm_r_orw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_orw\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s16));
        ibb->add (IA32OR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

        ibb->add (ST(TEMPREG1, t, 0, s16));
    }
}

//08 /r Ia_orb_Eb_Gb
void IA32Interpreter::rorm_r_orb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_orb\n");
    if (insn->mod == 3)
    {
        if (op->op2.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
				if( mode_ == NORMAL )
				{
					//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
					SET_FLAGS_ANDB( TEMPREG1 );
				}

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -= 4;
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32OR(VREG(op->op2.reg), TEMPREG3, TEMPREG1));
				if( mode_ == NORMAL )
				{
					//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
					SET_FLAGS_ANDB( TEMPREG1 );
				}

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
        else
        {
            op->op2.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
				if( mode_ == NORMAL )
				{
					//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
					SET_FLAGS_ANDB( TEMPREG1 );
				}

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
            else
            {
                insn->rm -=4;

                ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32OR(TEMPREG1, TEMPREG3, TEMPREG1));
				if( mode_ == NORMAL )
				{
					//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
					SET_FLAGS_ANDB( TEMPREG1 );
				}

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
                ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        if (op->op2.reg < 4)
        {
            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            ibb->add (IA32OR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 );
			}

            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
        else
        {
            op->op2.reg -= 4;

            ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
            ibb->add (LD(t, 0, TEMPREG1, s8));
            ibb->add (IA32OR(TEMPREG1, TEMPREG3, TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 );
			}

            ibb->add (ST(TEMPREG1, t, 0, s8));
        }
    }

}

// 0A /r Ia_orb_Gb_Eb
void IA32Interpreter::r_rorm_orb0a(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_orb0a\n");
    if (insn->mod == 3)
    {
        if (op->op1.reg < 4)
        {
            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32OR(VREG(op->op1.reg), VREG(insn->rm), TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -=4;
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG3, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32LI(0xffffff00, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
        else
        {
            op->op1.reg -= 4;

            if (insn->rm < 4)
            {
                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
            else
            {
                insn->rm -=4;

                ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
                ibb->add (IA32LI(0x8, TEMPREG2));
                ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
                ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
                ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
                ibb->add (IA32OR(TEMPREG1, TEMPREG3, TEMPREG1));
                //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 )

                ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
                ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
                ibb->add (IA32LI(0xffff00ff, TEMPREG2));
                ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
                ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
                ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
            }
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));

        if (op->op1.reg < 4)
        {
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32OR(TEMPREG1, VREG(op->op1.reg), TEMPREG1));
            //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
			SET_FLAGS_ANDB( TEMPREG1 )

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            op->op1.reg -= 4;

            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG3));
            ibb->add (IA32OR(TEMPREG1, TEMPREG3, TEMPREG1));
            //ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
			SET_FLAGS_ANDB( TEMPREG1 )

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
    }

    /*
       op_size = BYTE;
       if (insn->mod == 3)
       {
       ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
       ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
       ibb->add (IA32OR(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
       ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(op->op1.reg)));

       ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
       }
       else
       {
       XTRegNum t = resolveModRM(insn,op,bb);
       ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
       ibb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
       ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
       ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(op->op1.reg)));

       ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
       }
       */
}

//80 /1 Ia_orb_Eb_Ib
void IA32Interpreter::rorm_i_orb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_orb80\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 );
			}

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG2));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
            ibb->add (IA32OR(TEMPREG1, TEMPREG3, TEMPREG1));
			if( mode_ == NORMAL )
			{
				//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
				SET_FLAGS_ANDB( TEMPREG1 );
			}

            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32SLL(TEMPREG1, TEMPREG2, TEMPREG1));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI((Word)op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (IA32OR(TEMPREG2, TEMPREG1, TEMPREG2));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG2));
			SET_FLAGS_ANDB( TEMPREG2 );
		}

        ibb->add (ST(TEMPREG2, t, 0, s8));
    }

    /*
       op_size = BYTE;
       if (insn->mod == 3)
       {
       ibb->add (IA32LI(op->op2.imm, TEMPREG1));
       ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
       ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
       ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(insn->rm)));

       ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
       }
       else
       {
       XTRegNum t = resolveModRM(insn,op,bb);
       ibb->add (IA32LI(op->op2.imm, TEMPREG1));
       ibb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
       ibb->add (IA32OR(TEMPREG2, TEMPREG1, TEMPREG2));
       ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG2));

       ibb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
       }
       */
}

//81 /1 Ia_orl_Ed_Id
void IA32Interpreter::rorm_i_orl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_orl81\n");
    rorm_i_orl83(insn, op, bb);
}

//83 /1 Ia_orl_Ed_sIb
void IA32Interpreter::rorm_i_orl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_orl83\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));
			SET_FLAGS_ANDL( VREG(insn->rm) );
		}

        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32OR(TEMPREG2, TEMPREG1, TEMPREG2));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG2));
			SET_FLAGS_ANDL( TEMPREG2 );
		}
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

// 81 Ia_orw_Ew_Iw
void IA32Interpreter::rorm_i_orw81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_orw81\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (IA32OR(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1,TEMPREG2));

        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

//83 Ia_orw_Ew_sIb
void IA32Interpreter::rorm_i_orw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_orw83\n");
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

        ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG2));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (IA32OR(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1,TEMPREG2));

        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

//0b Ia_orl_Gd_Ed
void IA32Interpreter::rorm_i_orl0b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_orl0b\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));
			SET_FLAGS_ANDL( VREG(op->op1.reg) );
		}

        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		if( mode_ == NORMAL )
		{
			//ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));
			SET_FLAGS_ANDL( VREG(op->op1.reg) );
		}

        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 0C ib Ia_orb_AL_Ib
void IA32Interpreter::AL_i_orb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("AL_i_orb\n");
    ibb->add (IA32LI(op->op2.imm, TEMPREG1));
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));
		SET_FLAGS_ANDB( TEMPREG1 );
	}

    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
    ibb->add (IA32LI(0xffffff00, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//73 cb Ia_jnb_Jb  Note:jnb is the same of jae   (CF==0)
void IA32Interpreter::i_jnbb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnbb\n");
    ibb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    ibb->add(BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));	
}

//0F 83 cw Ia_jnb_Jd  Note:jnb is the same of jae   (CF==0)
void IA32Interpreter::i_jnbd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("i_jnbd\n");
    ibb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    ibb->add(BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));	
}

//90 Ia_nop
void IA32Interpreter::nop(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
}

//C1 /4 ib Ia_shll_Ed_Ib
void IA32Interpreter::rorm_i_shllc1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
	if(ptx_msg) printf("rorm_i_shllc1\n");
	if(mode_ == NORMAL)
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32LI(op->op2.imm, TEMPREG1));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
			ibb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, VREG(insn->rm), TEMPREG1));

			ibb->add (IA32SLL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
			ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32LI(op->op2.imm, TEMPREG1));
			ibb->add (LD(t, 0, TEMPREG2, s32));	
			ibb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, TEMPREG2, TEMPREG1));

			ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
			ibb->add (ST(TEMPREG2, t, 0, s32));	
		}
	}
	else if(mode_ == PTX)
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32LI(op->op2.imm, TEMPREG1));
			ibb->add (IA32GET(insn->rm, VREG(insn->rm)));

			ibb->add (IA32SLL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
			ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
		}
		else
		{
			XTRegNum t = resolveModRM(insn,op,bb);
			ibb->add (IA32LI(op->op2.imm, TEMPREG1));
			ibb->add (LD(t, 0, TEMPREG2, s32));	

			ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
			ibb->add (ST(TEMPREG2, t, 0, s32));	
		}
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

//D1 /4 Ia_shll_Ed
void IA32Interpreter::shlld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("shlld1\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, VREG(insn->rm), TEMPREG1));
		}

        ibb->add (IA32SLL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));	
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, TEMPREG2, TEMPREG1));
		}

        ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));	
    }
}

// 0f a5
void IA32Interpreter::shldl_cl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("shld1_c1\n");
    // printf("shldl_cl\n");
    // exit(0);
    /*
       XTRegNum t = resolveModRM(insn, op, bb);
       op_size = BYTE;
       ibb->add (IA32GET(IA32ProcessorState::ECX, t2));
       ibb->add (ZEXT(t2, BYTE, t2));
       op_size = WORD;
       if (insn->mod == 3)
       {
       ibb->add (IA32GET(insn->rm, t3));
       ibb->add (IA32SLL(t3, t2, t4));
       ibb->add (IA32PUT(t4, insn->rm));
       ibb->add (IA32LI(32, t1));
       ibb->add (IA32SUB(t1, t2, t1));
       ibb->add (IA32GET(op->op2.reg, t2));
       ibb->add (IA32SRL(t2, t1, t2));
       ibb->add (IA32GET(insn->rm,t1));
       ibb->add (IA32OR(t1, t2, t3));
       ibb->add (IA32PUT(t3, insn->rm));
       }
       else
       {
       printf("in shldl_c1\n");
       exit(0);
       ibb->add (LD(t, mm_->map(0), WORD, t3));
       ibb->add (IA32SLL(t3, t2, t4));
       ibb->add (ST(t4, WORD, t, mm_->map(0)));
       }
       */
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32LI(0xff, TEMPREG1));
        ibb->add (IA32AND(VREG(IA32ProcessorState::ECX), TEMPREG1, VREG(IA32ProcessorState::ECX)));

        ibb->add (IA32LI (32, TEMPREG1));
        ibb->add (IA32SUB(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, VREG(op->op2.reg)));

        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32MOV(VREG(op->op1.reg), TEMPREG1));
        // ibb->add (IA32LI (op->op3.imm, t3));
        ibb->add (IA32SLL(VREG(op->op1.reg), VREG(IA32ProcessorState::ECX), VREG(op->op1.reg)));
        ibb->add (IA32OR (VREG(op->op1.reg), VREG(op->op2.reg), VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shldl),3, TEMPREG1, VREG(op->op1.reg), VREG(IA32ProcessorState::ECX)));
		}
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);

        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32LI(0xff, TEMPREG1));
        ibb->add (IA32AND(VREG(IA32ProcessorState::ECX), TEMPREG1, VREG(IA32ProcessorState::ECX)));

        ibb->add (IA32LI (32, TEMPREG1));
        ibb->add (IA32SUB(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG1, VREG(op->op2.reg)));

        ibb->add (LD(t, 0, TEMPREG1, s32));	// M[t2] = t1
        ibb->add (IA32SLL(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG2));
        ibb->add (IA32OR (TEMPREG2, VREG(op->op2.reg), TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));	// M[t2] = t1

		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shldl),3, TEMPREG1, TEMPREG2, VREG(IA32ProcessorState::ECX)));
		}
    }


    //ibb->add (IA32LI((Word)state_, t4));
    //ibb->add (CALL((Word)(&crossbit::set_flags_shll),3,t4,t3,t2));
}

// Added by zhengjuyu
// There is a bug here, the eflags is wrong.
// 0f a4
void IA32Interpreter::rorm_r_i_shldl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_i_shldl\n");
    op_size = WORD;
    dtype = s32;
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op3.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32SLL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        //ibb->add (IA32PUT(t4, insn->rm));
        ibb->add (IA32LI(32, TEMPREG2));
        ibb->add (IA32SUB(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
        //ibb->add (IA32GET(insn->rm,t1));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        printf("in shldl_c1\n");
        exit(0);
        ibb->add (LD(t, 0, t3, s32));
        ibb->add (IA32SLL(t3, t2, t4));
        ibb->add (ST(t4, t, 0, s32));
    }

}

// Added by zhengjuyu
// There is a bug here, the eflags is wrong.
// 0f a5
void IA32Interpreter::shrdl_cl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("shrdl_cl\n");
    ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
    ibb->add (IA32LI(0x1f, TEMPREG1));
    ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (CMP(NE, 0, TEMPREG1, TEMPREG2));
        ibb->add (IA32SUB(0, TEMPREG2, TEMPREG2));
        ibb->add (IA32LI(32, TEMPREG3));
        ibb->add (IA32SUB(TEMPREG3, TEMPREG1, TEMPREG3));
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32AND(TEMPREG2, VREG(op->op2.reg), TEMPREG2));
        ibb->add (IA32SLL(TEMPREG2, TEMPREG3, TEMPREG2));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        printf("shrdl_c1\n");
        exit(0);
        ibb->add (LD(t, 0, t3, s32));
        ibb->add (IA32SRL(t3, t2, t4));
        ibb->add (ST(t4, t, 0, s32));
    }
}

// Added by zhengjuyu
//
void IA32Interpreter::sahf(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("sahf\n");
    /*
       ibb->add (IA32GET(IA32ProcessorState::EAX, t1));
       ibb->add (IA32LI(0x100, t2));
       ibb->add (IA32AND(t2, t1, t2));
       ibb->add (CMP(NE, t2, 0, t3));
       ibb->add (IA32PUT(t3, IA32ProcessorState::CF));

       ibb->add (IA32LI(0x400, t2));
       ibb->add (IA32AND(t2, t1, t2));
       ibb->add (CMP(NE, t2, 0, t3));
       ibb->add (IA32PUT(t3, IA32ProcessorState::PF));

       ibb->add (IA32LI(0x1000, t2));
       ibb->add (IA32AND(t2, t1, t2));
       ibb->add (CMP(NE, t2, 0, t3));
       ibb->add (IA32PUT(t3, IA32ProcessorState::AF));

       ibb->add (IA32LI(0x4000, t2));
       ibb->add (IA32AND(t2, t1, t2));
       ibb->add (CMP(NE, t2, 0, t3));
       ibb->add (IA32PUT(t3, IA32ProcessorState::ZF));

       ibb->add (IA32LI(0x8000, t2));
       ibb->add (IA32AND(t2, t1, t2));
       ibb->add (CMP(NE, t2, 0, t3));
       ibb->add (IA32PUT(t3, IA32ProcessorState::SF));
       */
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (CALL((Word)(&crossbit::set_flags_sahf), 1, VREG(IA32ProcessorState::EAX)));
}

// Added by zhengjuyu
// a bug here
void IA32Interpreter::bsfl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("bsfl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, t2));
        ibb->add (CMP(EQ, t2, 0, t3));
        ibb->add (IA32PUT(t3, IA32ProcessorState::ZF));
        ibb->add (BSF(t2, t3));
        ibb->add (IA32PUT(t3, op->op1.reg));
        printf("bsrl\n");
        exit(0);
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (CMP(EQ, TEMPREG1, 0, TEMPREG2));
        ibb->add (IA32PUT(TEMPREG2, IA32ProcessorState::ZF));
        ibb->add (BSF(TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// A bug here, it doesn't set the eflag
void IA32Interpreter::bsrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("bsrl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CMP(EQ, VREG(insn->rm), 0, TEMPREG1));
        ibb->add (IA32PUT(TEMPREG1, IA32ProcessorState::ZF));
        ibb->add (BSR(VREG(insn->rm), VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (CMP(EQ, TEMPREG1, 0, TEMPREG2));
        ibb->add (IA32PUT(TEMPREG2, IA32ProcessorState::ZF));
        ibb->add (BSR(TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//D3 /7 Ia_sarl_Ed_CL
void IA32Interpreter::rorm_CL_sarl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_CL_sarl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32LI(0x1f, TEMPREG1));
        ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32SRA(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32LI(0x1f, TEMPREG1));
        ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

//D1 /7 Ia_sarl_Ed
void IA32Interpreter::sarld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("sarld1\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32SRA(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

void IA32Interpreter::sarw_i1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("sarw_il\n");
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (SEXT(VREG(insn->rm), TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_sarw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (SEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_sarw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

//C1 /7 ib Ia_sarl_Ed_Ib
void IA32Interpreter::rorm_i_sarlc1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_sarlc1\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, VREG(insn->rm), TEMPREG1));
		}

        ibb->add (IA32SRA(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));	
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, TEMPREG2, TEMPREG1));
		}

        ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));	
    }
}

//
void IA32Interpreter::rorm_i_sarbc0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_sarbc0\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32LI(op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (SEXT(VREG(insn->rm), TEMPREG2, b8));
            ibb->add (CALL((Word)(&crossbit::set_flags_sarb), 2, TEMPREG2, TEMPREG1));

            ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32LI(op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG3, TEMPREG2));
            ibb->add (SEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (CALL((Word)(&crossbit::set_flags_sarb), 2, TEMPREG2, TEMPREG1));

            ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG3, TEMPREG2));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (SEXT(TEMPREG2, TEMPREG2, b8));
        ibb->add (CALL((Word)(&crossbit::set_flags_sarb), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRA(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s8));	
    }

}

//D3 /4 ib Ia_shll_Ed_CL
void IA32Interpreter::rorm_r_shlld3(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_shlld3\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, VREG(insn->rm), VREG(op->op2.reg)));
		}

        ibb->add (IA32SLL(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));	
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, TEMPREG1, VREG(op->op2.reg)));
		}

        ibb->add (IA32SLL(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s32));	
    }
}

//D1 /5 Ia_shrl_Ed
void IA32Interpreter::rorm_shrld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_shrld1\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, VREG(insn->rm), TEMPREG1));

        ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));	
        ibb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));	
    }
}

//D3 /4 ib Ia_shll_Ed_CL
void IA32Interpreter::rorm_r_shrld3(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_shrld3\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, VREG(insn->rm), VREG(op->op2.reg)));
		}

        ibb->add (IA32SRL(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (LD(t, 0, TEMPREG1, s32));	
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, TEMPREG1, VREG(op->op2.reg)));
		}

        ibb->add (IA32SRL(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s32));	
    }
}

//C1 /5 ib Ia_shrl_Ed_Ib
void IA32Interpreter::rorm_i_shrlc1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_i_shrlc1\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, VREG(insn->rm), TEMPREG1));
		}

        ibb->add (IA32SRL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s32));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, TEMPREG2, TEMPREG1));
		}

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

// D1 Ia_shlw_Ew_I1
void IA32Interpreter::rorm_shlw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_shlw\n");

    if (insn->mod == 3)
    {
        ibb->add (IA32LI(1, TEMPREG1));

        //op_size = HALFWORD;
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (ZEXT(VREG(insn->rm), TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_shlw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));	
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_shlw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SLL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

// D0 /5 Ia_shrb_Eb
void IA32Interpreter::rorm_shrb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_shrb\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32LI(1, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (ZEXT(VREG(insn->rm), TEMPREG2, b8));
            ibb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

            ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32LI(1, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG3, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

            ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG3, TEMPREG2));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
        ibb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s8));	
    }

}

// C0 /5 ib Ia_shrb_Eb_Ib
void IA32Interpreter::shrb_ib(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("shrb_ib\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32LI(op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (ZEXT(VREG(insn->rm), TEMPREG2, b8));
			if( mode_ == NORMAL )
			{
				ibb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));
			}

            ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32LI(op->op2.imm, TEMPREG1));
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32LI(0x8, TEMPREG3));
            ibb->add (IA32SRL(VREG(insn->rm), TEMPREG3, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
			if( mode_ == NORMAL )
			{
				ibb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));
			}

            ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
            ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
            ibb->add (IA32SLL(TEMPREG2, TEMPREG3, TEMPREG2));
            ibb->add (IA32LI(0xffff00ff, TEMPREG1));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s8));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b8));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));
		}

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s8));	
    }
}

// D1 /5 Ia_shrw_Ew
void IA32Interpreter::shrw_i1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("shrw_il\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(1, TEMPREG1));

        //op_size = HALFWORD;
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (ZEXT(VREG(insn->rm), TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(1, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s16));	
    }
}

// C1 /5 ib Ia_shrw_Ew_Ib
void IA32Interpreter::shrw_ib(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("shrw_ib\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));

        //op_size = HALFWORD;
        ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add (ZEXT(VREG(insn->rm), TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (IA32LI(0xffff0000, TEMPREG1));
        ibb->add (IA32AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        ibb->add (IA32OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
        ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (IA32LI(op->op2.imm, TEMPREG1));
        ibb->add (LD(t, 0, TEMPREG2, s16));	
        ibb->add (ZEXT(TEMPREG2, TEMPREG2, b16));
        ibb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

        ibb->add (IA32SRL(TEMPREG2, TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s16));
    }
}

void IA32Interpreter::rorm_notb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_notb\n");
    if (insn->mod == 3)
    {
        if (insn->rm < 4)
        {
            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32NOT(VREG(insn->rm), TEMPREG1));
            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b8));
            ibb->add (IA32LI(0xffffff00, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
        else
        {
            insn->rm -= 4;

            ibb->add (IA32GET(insn->rm, VREG(insn->rm)));
            ibb->add (IA32NOT(VREG(insn->rm), TEMPREG1));
            ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
            ibb->add (IA32LI(0xff00, TEMPREG2));
            ibb->add (IA32AND(TEMPREG1, TEMPREG2, TEMPREG1));
            ibb->add (IA32LI(0xffff00ff, TEMPREG2));
            ibb->add (IA32AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
            ibb->add (IA32OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
            ibb->add (IA32PUT(VREG(insn->rm), insn->rm));
        }
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s8));
        ibb->add (IA32NOT(TEMPREG1, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s8));
    }

}

//F7 /2 Ia_notl_Ed
void IA32Interpreter::rorm_notl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_notl\n");
    if (insn->mod == 3)
    {
        ibb->add(IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add(IA32NOT(VREG(op->op1.reg), VREG(op->op1.reg)));
        ibb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32NOT(TEMPREG1, TEMPREG2));
        ibb->add (ST(TEMPREG2, t, 0, s32));
    }
}

//F7 /3 Ia_negl_Ed
//Note:This operation is equivalent to subtracting the operand from 0.
void IA32Interpreter::rorm_negl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_negl\n");
    ibb->add(IA32LI(0, TEMPREG1));
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_negl),1, VREG(op->op1.reg)));
		}
        ibb->add (IA32SUB(TEMPREG1, VREG(op->op1.reg), VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG2, s32));
		if( mode_ == NORMAL )
		{
			ibb->add (CALL((Word)(&crossbit::set_flags_negl), 1, TEMPREG2));
		}
        ibb->add (IA32SUB(TEMPREG1, TEMPREG2, TEMPREG1));
        ibb->add (ST(TEMPREG1, t, 0, s32));
    }
}

//F7 /6 Ia_divl_EAX_Ed
void IA32Interpreter::EAX_rorm_divl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("EAX_rorm_divl\n");
    if (insn->mod == 3)
    {
        ibb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add(IA32GET(IA32ProcessorState::EDX, VREG(IA32ProcessorState::EDX)));
        ibb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add(DIVU64(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX), VREG(op->op2.reg),
                    TEMPREG2, TEMPREG3));
        ibb->add(IA32MOV(TEMPREG2, VREG(IA32ProcessorState::EAX)));
        ibb->add(IA32MOV(TEMPREG3, VREG(IA32ProcessorState::EDX)));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add(IA32GET(IA32ProcessorState::EDX, VREG(IA32ProcessorState::EDX)));
        ibb->add(DIVU64(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX), TEMPREG1,
                    TEMPREG2, TEMPREG3));
        ibb->add(IA32MOV(TEMPREG2, VREG(IA32ProcessorState::EAX)));
        ibb->add(IA32MOV(TEMPREG3, VREG(IA32ProcessorState::EDX)));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
}

// There is a bug here, the IA32DIV is defined as EDX:EAX / src,
// But now there is only EAX / src
// added by zhengjuyu
// f7
void IA32Interpreter::idivf7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("idivf7\n");

    if (insn->mod == 3)
    {
        ibb->add(IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add(IA32DIV(VREG(IA32ProcessorState::EAX), VREG(insn->rm), VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX)));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32DIV(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
}

// added by zhengjuyu
// f7
void IA32Interpreter::imulf7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("imulf7\n");
    if (insn->mod == 3)
    {
        ibb->add(IA32GET(insn->rm, VREG(insn->rm)));
        ibb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add(IA32MUL(VREG(IA32ProcessorState::EAX), VREG(insn->rm), VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
        ibb->add(IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32MUL(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
	if( mode_ == NORMAL )
	{
		//ibb->add(CALL((Word)(&crossbit::set_flags_imull), 1, VREG(IA32ProcessorState::EDX)));
		SET_FLAGS_IMULL( VREG(IA32ProcessorState::EDX) );
	}
}


//There maybe a bug here.
//added by Chuchao
//0F AF Ia_imull_Gw_Ew
void IA32Interpreter::r_rorm_imulw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_imulw\n");
    //printf("r_rorm_imulw: 0x%08x\n", op->op3.imm);

    op_size = HALFWORD;
    dtype = s16;

    if (insn->mod == 3)
    {
        ibb->add(IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add(IA32MUL(VREG(op->op1.reg), VREG(op->op2.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32MUL(VREG(op->op1.reg), TEMPREG1, TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg),op->op1.reg));
    }

    //ibb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG2));
	SET_FLAGS_IMULL( TEMPREG2 )
}

//0F AF Ia_imull_Gd_Ed
void IA32Interpreter::r_rorm_imull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_imull\n");
    if(mode_ == NORMAL)
    {
        if (insn->mod == 3)
        {
            ibb->add(IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add(IA32MUL(VREG(op->op1.reg), VREG(op->op2.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (LD(t, 0, TEMPREG1, s32));
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32MUL(VREG(op->op1.reg), TEMPREG1, TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg),op->op1.reg));
        }

		if( mode_ == NORMAL )
		{
			//ibb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG2));
			SET_FLAGS_IMULL( TEMPREG2 );
		}
	}
    else if(mode_ == PTX)
    {
        if (insn->mod == 3)
        {
            ibb->add(IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
            ibb->add(IA32MUL(VREG(op->op1.reg), VREG(op->op2.reg), TEMPREG2, VREG(op->op1.reg)));
            ibb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
        }
        else
        {
            XTRegNum t = resolveModRM(insn,op,bb);
            ibb->add (LD(t, 0, TEMPREG1, s32));
            ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
            ibb->add (IA32MUL(VREG(op->op1.reg), TEMPREG1, TEMPREG2, VREG(op->op1.reg)));
            ibb->add (IA32PUT(VREG(op->op1.reg),op->op1.reg));
        }
    }
    else
    {
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
    }
}


// 69 /r id 
void IA32Interpreter::imull_id(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("imull_id\n");
    ibb->add(IA32LI(op->op3.imm, TEMPREG1));
    if (insn->mod == 3)
    {
        ibb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add(IA32MUL(VREG(op->op2.reg), TEMPREG1, TEMPREG3, VREG(op->op1.reg)));
        ibb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (LD(t, 0, TEMPREG2, s32));
        ibb->add (IA32MUL(TEMPREG2, TEMPREG1, TEMPREG3, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

    //ibb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG3));
	SET_FLAGS_IMULL( TEMPREG3 )
}

//6B Ia_imull_Gd_Ed_sIb
void IA32Interpreter::r_rorm_i_imull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_imull\n");
    ibb->add(IA32LI(op->op3.imm, TEMPREG1));
    if (insn->mod == 3)
    {
        ibb->add(IA32GET(op->op2.reg ,VREG(op->op2.reg)));
        ibb->add(IA32MUL(TEMPREG1, VREG(op->op2.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add(IA32PUT(VREG(op->op1.reg) ,op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        ibb->add (LD(t, 0, TEMPREG3, s32));
        ibb->add (IA32MUL(TEMPREG1, TEMPREG3, TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg) ,op->op1.reg));
    }
    //ibb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG2));
	SET_FLAGS_IMULL( TEMPREG2 )

}

//F7 /4 Ia_mull_EAX_Ed
void IA32Interpreter::EAX_rorm_mull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{ 
    if(ptx_msg) printf("EAX_rorm_mull\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32MULU(VREG(IA32ProcessorState::EAX), VREG(op->op2.reg), VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));
        ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32MULU(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_imull),1, VREG(IA32ProcessorState::EDX)));
		SET_FLAGS_IMULL( VREG(IA32ProcessorState::EDX) );
	}
}

//FC Ia_cld
void IA32Interpreter::cld(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("cld\n");
    ibb->add(IA32PUT(0, IA32ProcessorState::DF));
}

//A4 Ia_movsb_Yb_Xb
void IA32Interpreter::m_m_movsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("m_m_movsb\n");
    op_size = WORD;
    dtype = s32;

    ibb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    ibb->add (USE(IA32ProcessorState::ESI));
    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0));
    }

    // There may be a bug here!
    ibb->add (LD(VREG(IA32ProcessorState::ESI), 0, TEMPREG1, s8));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESI), 1, VREG(IA32ProcessorState::ESI)));
    ibb->add (ST(TEMPREG1, VREG(IA32ProcessorState::EDI), 0, s8));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
        ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        ibb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// A6 Ia_cmpsb_Yb_Xb
void IA32Interpreter::cmpsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("cmpsb\n");
    op_size = WORD;
    dtype = s32;

    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));
    ibb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    ibb->add (USE(IA32ProcessorState::ESI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0));
    }

    ibb->add (LD(VREG(IA32ProcessorState::EDI), 0, TEMPREG1, s32));
    ibb->add (LD(VREG(IA32ProcessorState::ESI), 0, TEMPREG2, s32));
    //ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));
	// added by zhangyichao, 2010-4-15
	SET_FLAGS_SUBB(TEMPREG2, TEMPREG1)

    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESI), 1, VREG(IA32ProcessorState::ESI)));

    if (hasRep)
    {
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));

        if (repFlag == 1)
        {
            ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
            ibb->add (IA32SUBI(TEMPREG1, 1, TEMPREG1));
            ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
            ibb->add (LOOPN(TEMPREG1, 0, 0));
            ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        }
        else
        {
            ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
            ibb->add (IA32NOT(TEMPREG1, TEMPREG1));
            ibb->add (IA32ADDI(TEMPREG1, 1, TEMPREG1));
            ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
            ibb->add (LOOPN(TEMPREG1, 0, 0));
            ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        }

        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
}

//AE Ia_scasb_Yb_AL
void IA32Interpreter::m_r_scasb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("m_r_scasb\n");
    op_size = WORD;
    dtype = s32;

    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (USE(IA32ProcessorState::EAX));
    ibb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    ibb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
        ibb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
        ibb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
        ibb->add (LABEL(0));
    }

    ibb->add (LD(VREG(IA32ProcessorState::EDI), 0, TEMPREG1, s32));
	if( mode_ == NORMAL )
	{
		//ibb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
		// added by zhangyichao, 2010-4-15
		SET_FLAGS_SUBB(VREG(IA32ProcessorState::EAX), TEMPREG1);
	}
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));
    if (hasRep)
    {
        ibb->add (IA32SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));

        if (repFlag == 1)
        {
            ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
            ibb->add (IA32SUBI(TEMPREG1, 1, TEMPREG1));
            ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
            ibb->add (LOOPN(TEMPREG1, 0, 0));
            ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        }
        else
        {
            ibb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
            ibb->add (IA32NOT(TEMPREG1, TEMPREG1));
            ibb->add (IA32ADDI(TEMPREG1, 1, TEMPREG1));
            ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
            ibb->add (LOOPN(TEMPREG1, 0, 0));
            ibb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
        }

        hasRep = false;
        ibb->add (LABEL(1));
    }

    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

//C9 Ia_leave
void IA32Interpreter::leave(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("leave\n");
    ibb->add (IA32GET(IA32ProcessorState::EBP, VREG(IA32ProcessorState::EBP)));
    ibb->add (IA32MOV(VREG(IA32ProcessorState::EBP), VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));

    ibb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    ibb->add (LD(VREG(IA32ProcessorState::ESP), 0, VREG(IA32ProcessorState::EBP), s32));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EBP), IA32ProcessorState::EBP));
    //ibb->add (IA32LI(4, TEMPREG1));
    //ibb->add (IA32ADD(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32ADDI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
}

//86 Ia_xchgb_Eb_Gb
void IA32Interpreter::r_rorm_xchgb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_rorm_xchgb\n");
    op_size = BYTE;
    dtype = s8;
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32MOV(VREG(op->op2.reg), TEMPREG1));
        ibb->add (IA32MOV(VREG(op->op1.reg), VREG(op->op2.reg)));
        ibb->add (IA32MOV(TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (LD(t, 0, TEMPREG1, s8));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (ST(VREG(op->op1.reg), t, 0, dtype));

        ibb->add (IA32MOV(TEMPREG1, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//87 Ia_xchgl_Ed_Gd
void IA32Interpreter::rorm_r_xchgl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("rorm_r_xchgl\n");
    if (insn->mod == 3)
    {
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

        ibb->add (IA32MOV(VREG(op->op2.reg), TEMPREG1));
        ibb->add (IA32MOV(VREG(op->op1.reg), VREG(op->op2.reg)));
        ibb->add (IA32MOV(TEMPREG1, VREG(op->op1.reg)));

        ibb->add (IA32PUT(VREG(op->op1.reg),op->op1.reg));
        ibb->add (IA32PUT(VREG(op->op2.reg),op->op2.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        ibb->add (LD(t, 0, TEMPREG1, s32));	
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (ST(VREG(op->op2.reg), t, 0, dtype));	

        ibb->add (IA32MOV(TEMPREG1, VREG(op->op2.reg)));
        ibb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
    }
}

//49 Ia_decl_ERX
void IA32Interpreter::r_decl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("r_decl\n");
	if(mode_ == NORMAL)
	{
		ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		//ibb->add (IA32LI(1, TEMPREG1));
		//ibb->add (CALL((Word)(&crossbit::set_flags_decl1), 1, VREG(op->op1.reg)));
		SET_FLAGS_DECL1( VREG(op->op1.reg) )

		ibb->add (IA32SUBI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
		ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else if(mode_ == PTX)
	{
		ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

		ibb->add (IA32SUBI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
		ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
		UTIL::XTLOG("unknown interp mode!\n");
		exit(0);
	}
}

// FF Ia_decl_Ed
void IA32Interpreter::m_decl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("m_decl\n");
	if( mode_ == NORMAL )
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
			//ibb->add (IA32LI(1, TEMPREG1));
			//ibb->add (CALL((Word)(&crossbit::set_flags_decl1), 1, VREG(op->op1.reg)));
			SET_FLAGS_DECL1( VREG(op->op1.reg) );

			ibb->add (IA32SUBI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
			ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
		}
		else
		{
			XTRegNum t = resolveModRM(insn, op, bb);
			ibb->add (LD(t, 0, TEMPREG1, dtype));
			//ibb->add (IA32LI(1, TEMPREG2));
			//ibb->add (CALL((Word)(&crossbit::set_flags_decl1), 1, TEMPREG1));
			SET_FLAGS_DECL1( TEMPREG1 );

			ibb->add (IA32SUBI(TEMPREG1, 1, TEMPREG1));
			ibb->add (ST(TEMPREG1, t, 0, dtype));
		}
	}
	else if( mode_ == PTX )
	{
		if (insn->mod == 3)
		{
			ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

			ibb->add (IA32SUBI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
			ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
		}
		else
		{
			XTRegNum t = resolveModRM(insn, op, bb);
			ibb->add (LD(t, 0, TEMPREG1, dtype));

			ibb->add (IA32SUBI(TEMPREG1, 1, TEMPREG1));
			ibb->add (ST(TEMPREG1, t, 0, dtype));
		}
	}
	else
	{
		UTIL::XTLOG("unknown interp mode!\n");
		exit(0);
	}
}

// The Float Control word is unused now!
// So the FPU may not perform well in some case!
void IA32Interpreter::f_fnstcw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("f_fnstcw\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32GET(IA32ProcessorState::FControl,t2));
    ibb->add (ST(t2, t, 0, s16));
}

// The Float Control word is unused now!
// So the FPU may not perform well in some case!
void IA32Interpreter::f_fldcw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("f_fldcw\n");
    // printf("f_fldcw: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(t, 0, t2, s16));
    ibb->add (IA32PUT(t2, IA32ProcessorState::FControl));	
}

// Added by zhengjuyu
// frndint
void IA32Interpreter::frndint(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("frndint\n");

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    ibb->add (FRNDINT());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// fildl
void IA32Interpreter::fildl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fildl\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (IA32LI(1, t3));
    ibb->add (IA32SUB(t2, t3, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (ST(t2, 0, (MemAddr)&top, s32));

    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, WORD, t2, DOUBLE));
}

// Added by zhengjuyu
// fildq
void IA32Interpreter::fildq(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fildq\n");
    XTRegNum t = resolveModRM(insn,op,bb);

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t2, s32));
		ibb->add (IA32LI(1, t3));
		ibb->add (IA32SUB(t2, t3, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (ST(t2, 0, (MemAddr)&top, s32));

		ibb->add (FLD(t, mm_->map(0), DWORD, t2));
		ibb->add (FCONV(t2, DWORD, t2, DOUBLE));
	}
	else if( mode_ == PTX )
	{
		RegNum freg = ibb->getFtop();
		ibb->add( FLD( t, mm_->map(0), DWORD, freg ) );
		ibb->add( FCONV( freg, DWORD, freg, DOUBLE ) );
		ibb->incFtop();
	}
	else
	{
		UTIL::XTLOG("unknown interp mode!\n");
		exit(0);
	}
}

// Added by zhengjuyu
// filds
void IA32Interpreter::filds(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("filds\n");
    XTRegNum t = resolveModRM(insn,op,bb);

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t2, s32));
		ibb->add (IA32LI(1, t3));
		ibb->add (IA32SUB(t2, t3, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (ST(t2, 0, (MemAddr)&top, s32));

		ibb->add (FLD(t, mm_->map(0), WORD, t2));
		//ibb->add (LD(0, (MemAddr)&top, WORD, t2));
		ibb->add (FCONV(t2, HALFWORD, t2, DOUBLE));
	}
	else if( mode_ == PTX )
	{
		RegNum freg = ibb->getFtop();
		ibb->add( FLD( t, mm_->map(0), WORD, freg ) );
		ibb->add( FCONV( freg, HALFWORD, freg, DOUBLE ) );
		ibb->incFtop();
	}
	else
	{
		UTIL::XTLOG("unknown interp mode!\n");
		exit(0);
	}
}

// Added by zhengjuyu
// fimull
void IA32Interpreter::fimull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fimull\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, WORD, t2, DOUBLE));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    //ibb->add (FMULD());
    ibb->add (MUL(t2, t3, -1, t3, -1, f64));
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fchs
void IA32Interpreter::fchs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fchs\n");
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    ibb->add (FCHS());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// fadds
void IA32Interpreter::fadds(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fadds\n");
    XTRegNum t = resolveModRM(insn,op,bb);

	if(mode_ == NORMAL)
	{
		ibb->add (IA32LI(8, t2));
		ibb->add (FLD(t, mm_->map(0), WORD, t2));
		ibb->add (FCONV(t2, FLOAT, t2, DOUBLE));
		ibb->add (LD(0, (MemAddr)&top, t3, s32));
		ibb->add (FGETD(t3));
		ibb->add (IA32LI(8, t2));
		ibb->add (FGETD(t2));
		//ibb->add (FADDD());
		ibb->add (ADD(t2, t3, t3, f64));
		//ibb->add (LD(0, (MemAddr)&top, WORD, t3));
		ibb->add (FPUTD(t3));
	}
	else if(mode_ == PTX)
	{
		XTRegNum m32int, st0;

		m32int = ibb->getFtop();
		ibb->add (FLD(t, mm_->map(0), WORD, m32int));
		ibb->incFtop();
		ibb->add (FCONV(m32int, FLOAT, m32int, DOUBLE));
		ibb->decFtop();
		ibb->decFtop();
		st0 = ibb->getFtop();
		ibb->add (ADD(m32int, st0, st0, f64));
		ibb->incFtop();
	}
	else
	{
		UTIL::XTLOG("unknown interp mode!\n");
		exit(0);
	}
}

// Added by zhengjuyu
// faddl
void IA32Interpreter::faddl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("faddl\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (FGETD(t2));
    //ibb->add (FADDD());
    ibb->add (ADD(t2, t3, t3, f64));
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubl
void IA32Interpreter::fsubl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsubl\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (FSUBD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubrl
void IA32Interpreter::fsubrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsubrl\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t2));
    ibb->add (FGETD(t3));
    ibb->add (FSUBD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubrs
void IA32Interpreter::fsubrs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsubrs\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (IA32LI(8, t2));
    ibb->add (FCONV(t2, FLOAT, t2, DOUBLE));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));

    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (FSUBD());

    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubs
void IA32Interpreter::fsubs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsubs\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, FLOAT, t2, DOUBLE));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    //ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (FSUBD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fisubl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fisubl\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, WORD, t2, DOUBLE));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (FSUBD());
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fisubrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fisubrl\n");
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, WORD, t2, DOUBLE));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (FSUBD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fabs
void IA32Interpreter::fabs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fabs\n");
    //printf("fabs: 0x%08x\n", op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    ibb->add (FABSD());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fldl2e(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fld12e\n");
    //printf("fldl2e: 0x%08x\n", op->op3.imm);

    ibb->add (FLDL2E());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32SUB(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fldlg2(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fldlg2: 0x%08x\n", op->op3.imm);

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (FGETD(t1));
    //ibb->add (FABSD());
    ibb->add (FLDLG2());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32SUB(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fldln2(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fldln2: 0x%08x\n", op->op3.imm);

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (FGETD(t1));
    //ibb->add (FABSD());
    ibb->add (FLDLN2());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32SUB(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fyl2x(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fyl2x\n");
    //printf("fyl2x: 0x%08x\n", op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FYL2X());

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (ST(t2, 0, (MemAddr)&top, s32));

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
void IA32Interpreter::fyl2xp1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fyl2xp1\n");
    //printf("fyl2xp1: 0x%08x\n", op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FYL2XP1());

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (ST(t2, 0, (MemAddr)&top, s32));

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
// faddp
void IA32Interpreter::faddp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("faddp\n");

    if(mode_ == NORMAL)
    {
        ibb->add (LD(0, (MemAddr)&top, t1, s32));
        ibb->add (IA32LI(insn->rm, t2));
        ibb->add (IA32ADD(t2, t1, t2));
        ibb->add (IA32LI(0x7, t3));
        ibb->add (IA32AND(t2, t3, t2));

        ibb->add (FGETD(t2));
        ibb->add (FGETD(t1));
        //ibb->add (FADDD());
        ibb->add (ADD(t1, t2, t2, f64));

        ibb->add (FPUTD(t2));

        ibb->add (IA32LI(1, t2));
        ibb->add (IA32ADD(t1, t2, t1));
        ibb->add (IA32LI(0x7, t2));
        ibb->add (IA32AND(t1, t2, t1));
        ibb->add (ST(t1, 0, (MemAddr)&top, s32));
    }
    else if(mode_ == PTX)
    {
        RegNum freg1, freg2;

        ibb->decFtop();
        freg1 = ibb->getFtop();
        //ibb->add (FGETD(freg1));
        ibb->decFtop();
        freg2 = ibb->getFtop();
        //ibb->add (FGETD(freg2));
        ibb->add (ADD(freg1, freg2, freg2, f64));

        ibb->incFtop();
    }
    else
    {
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
    }
}

// Added by zhengjuyu
// fiaddl
void IA32Interpreter::fiaddl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fiaddl\n");
    //printf("fiaddl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, WORD, t2, DOUBLE));
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    //ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    //ibb->add (FADDD());
    ibb->add (ADD(t1, t2, t1, f64));
    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fadd_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fadd_st0_sti\n");
    //printf("fadd_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    //ibb->add (FADDD());
    ibb->add (ADD(t1, t2, t1, f64));
    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fadd_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fadd_sti_st0\n");
    //printf("fadd_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    //ibb->add (FADDD());
    ibb->add (ADD(t1, t2, t2, f64));

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (IA32LI(insn->rm, t2));
    //ibb->add (IA32ADD(t2, t1, t2));
    //ibb->add (IA32LI(0x7, t3));
    //ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsub_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsub_st0_sti\n");
    //printf("fsub_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t1));
    ibb->add (FGETD(t2));
    ibb->add (FSUBD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsubr_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsubr_st0_sti\n");
    //printf("fsubr_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FSUBD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by chuchao
// DC E3
void IA32Interpreter::fsubr_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsubr_sti_st0\n");
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t1));
    ibb->add (FGETD(t2));
    ibb->add (FSUBD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsub_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsub_sti_st0\n");
    //printf("fsub_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FSUBD());

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (IA32LI(insn->rm, t2));
    //ibb->add (IA32ADD(t2, t1, t2));
    //ibb->add (IA32LI(0x7, t3));
    //ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsubp_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //no verify
    if(ptx_msg) printf("fsubp_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

	if(mode_ == NORMAL)
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (IA32LI(insn->rm, t2));
		ibb->add (IA32ADD(t2, t1, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));

		ibb->add (FGETD(t2));
		ibb->add (FGETD(t1));
		ibb->add (FSUBD());

		//ibb->add (LD(0, (MemAddr)&top, WORD, t1));
		//ibb->add (IA32LI(insn->rm, t2));
		//ibb->add (IA32ADD(t2, t1, t2));
		//ibb->add (IA32LI(0x7, t3));
		//ibb->add (IA32AND(t2, t3, t2));
		ibb->add (FPUTD(t2));

		//ibb->add (LD(0, (MemAddr)&top, WORD, t1));
		ibb->add (IA32LI(1, t2));
		ibb->add (IA32ADD(t1, t2, t1));
		ibb->add (IA32LI(0x7, t2));
		ibb->add (IA32AND(t1, t2, t1));
		ibb->add (ST(t1, 0, (MemAddr)&top, s32));
	}
	else if(mode_ == PTX)
	{
		XTRegNum st0, sti;

		st0 = ibb->getFtop();
		sti = ibb->getFtop() - insn->rm;

		ibb->add (SUB(sti, st0, sti, f64));
		ibb->decFtop();
	}
	else
	{
		UTIL::XTLOG("unknown interp mode!\n");
		exit(0);
	}
}

// Added by zhengjuyu
// 
// Subtract ST(i) from ST(0), store result in ST(i), and pop register stack.
void IA32Interpreter::fsubrp_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsubrp_sti_st0\n");
    //printf("top: %d\n", top);
    //printf("fsubrp_st0_sti st(%d)\n", insn->rm); 

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (IA32LI(insn->rm, t2));
		ibb->add (IA32ADD(t2, t1, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));

		ibb->add (FGETD(t1));
		ibb->add (FGETD(t2));
		ibb->add (SUB(t1, t2, t2, f64));
		//ibb->add (FSUBD());

		//ibb->add (LD(0, (MemAddr)&top, WORD, t1));
		//ibb->add (IA32LI(insn->rm, t2));
		//ibb->add (IA32ADD(t2, t1, t2));
		//ibb->add (IA32LI(0x7, t3));
		//ibb->add (IA32AND(t2, t3, t2));
		ibb->add (FPUTD(t2));

		//ibb->add (LD(0, (MemAddr)&top, WORD, t1));
		ibb->add (IA32LI(1, t2));
		ibb->add (IA32ADD(t1, t2, t1));
		ibb->add (IA32LI(0x7, t2));
		ibb->add (IA32AND(t1, t2, t1));
		ibb->add (ST(t1, 0, (MemAddr)&top, s32));
	}
	else if( mode_ == PTX )
	{
		ibb->decFtop();
		RegNum st0 = ibb->getFtop();
		RegNum sti = st0 - insn->rm;

		ibb->add( SUB( st0, sti, sti, f64 ) );
	}
	else
	{
		UTIL::XTLOG("unknown interp mode!\n");
		exit(0);
	}
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmul_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fmul_st0_sti\n");

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (IA32LI(insn->rm, t2));
		ibb->add (IA32ADD(t2, t1, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (FGETD(t2));
		ibb->add (FGETD(t1));
		//ibb->add (FMULD());
		ibb->add (MUL(t1, t2, -1, t1, -1, f64));
		//ibb->add (LD(0, (MemAddr)&top, WORD, t1));
		ibb->add (FPUTD(t1));
	}
	else if( mode_ == PTX )
	{
		XTRegNum freg1, freg2;

        ibb->decFtop();
        freg1 = ibb->getFtop();
        freg2 = freg1 - insn->rm;;
		// modified at 2009-12-25, change dest from freg1 to freg2
		ibb->add (MUL(freg1, freg2, -1, freg1, -1, f64));

		// commented at 2009-12-25
        ibb->incFtop();
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmul_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fmul_sti_st0\n");
    //printf("fmul_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    //ibb->add (FMULD());
    ibb->add (MUL(t1, t2, -1, t2, -1, f64));

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (IA32LI(insn->rm, t2));
    //ibb->add (IA32ADD(t2, t1, t2));
    //ibb->add (IA32LI(0x7, t3));
    //ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmulp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fmulp\n");
    //printf("fmulp: 0x%08x\n", op->op3.imm); 
	
	if(mode_ == NORMAL)
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (IA32LI(insn->rm, t2));
		ibb->add (IA32ADD(t2, t1, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (FGETD(t2));
		ibb->add (FGETD(t1));
		//ibb->add (FMULD());
		ibb->add (MUL(t1, t2, -1, t2, -1, f64));

		ibb->add (FPUTD(t2));

		ibb->add (IA32LI(1, t2));
		ibb->add (IA32ADD(t1, t2, t1));
		ibb->add (IA32LI(0x7, t2));
		ibb->add (IA32AND(t1, t2, t1));
		ibb->add (ST(t1, 0, (MemAddr)&top, s32));
	}
	else if(mode_ == PTX)
	{
		XTRegNum freg1, freg2;

        ibb->decFtop();
        freg1 = ibb->getFtop();
		//ibb->add (FGETD(freg1));
        ibb->decFtop();
        freg2 = ibb->getFtop();
		//ibb->add (FGETD(freg2));
		// modified at 2009-12-25, change dest from freg1 to freg2
		ibb->add (MUL(freg2, freg1, -1, freg2, -1, f64));

		// commented at 2009-12-25
        ibb->incFtop();
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fmull\n");

	if(mode_ == NORMAL)
	{
		XTRegNum t = resolveModRM(insn,op,bb);

		ibb->add (IA32LI(8, t2));
		ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
		ibb->add (FGETD(t2));
		ibb->add (LD(0, (MemAddr)&top, t3, s32));
		ibb->add (FGETD(t3));
		//ibb->add (FMULD());
		ibb->add (MUL(t2, t3, -1, t3, -1, f64));
		//ibb->add (LD(0, (MemAddr)&top, WORD, t3));
		ibb->add (FPUTD(t3));
	}
	else if(mode_ == PTX)
	{
		XTRegNum t = resolveModRM(insn,op,bb);
        XTRegNum freg1, freg2;

		ibb->add (FLD(t, mm_->map(0), DOUBLE, ibb->getFtop()));
        ibb->incFtop();
        ibb->decFtop();
        freg1 = ibb->getFtop();
        ibb->decFtop();
        freg2 = ibb->getFtop();
		ibb->add (MUL(freg1, freg2, -1, freg2, -1, f64));
		//ibb->add (FPUTD(freg2));
		ibb->incFtop();
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmuls(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fmuls\n"); 
    //printf("fmuls: 0x%08x\n", op->op3.imm); 

    if(mode_ == NORMAL)
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (IA32LI(8, t2));
        ibb->add (FLD(t, mm_->map(0), WORD, t2));
        ibb->add (FCONV(t2, FLOAT, t2, DOUBLE));
        ibb->add (FGETD(t2));
        ibb->add (LD(0, (MemAddr)&top, t3, s32));
        ibb->add (FGETD(t3));
        //ibb->add (FMULD());
        ibb->add (MUL(t2, t3, -1, t3, -1, f64));
        ibb->add (FPUTD(t3));
    }
    else if(mode_ == PTX)
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        XTRegNum freg1, freg2;

        ibb->add (FLD(t, 0, WORD, ibb->getFtop()));
        ibb->add (FCONV(ibb->getFtop(), FLOAT, ibb->getFtop(), DOUBLE));
        ibb->incFtop();
        ibb->decFtop();
        freg1 = ibb->getFtop();
        //ibb->add (FGETD(freg1));
        ibb->decFtop();
        freg2 = ibb->getFtop();
        //ibb->add (FGETD(freg2));
        ibb->add (MUL(freg1, freg2, -1, freg2, -1, f64));
        ibb->incFtop();
    }
    else
    {
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
    }
}

// Added by zhengjuyu
//
void IA32Interpreter::fst_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fst_sti\n");
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FGETD(t1));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
//
// Copy ST(0) to ST(i) and pop register stack
void IA32Interpreter::fstp_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fstp_sti\n");
    //printf("fstp st(%d): 0x%08x\n", insn->rm, op->op3.imm);

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (IA32LI(insn->rm, t2));
		ibb->add (IA32ADD(t2, t1, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (FGETD(t1));
		ibb->add (FPUTD(t2));
		//ibb->add (LD(0, (MemAddr)&top, WORD, t1));
		ibb->add (IA32LI(1, t2));
		ibb->add (IA32ADD(t1, t2, t1));
		ibb->add (IA32LI(0x7, t2));
		ibb->add (IA32AND(t1, t2, t1));
		ibb->add (ST(t1, 0, (MemAddr)&top, s32));
	}
	else if( mode_ == PTX )
	{
		ibb->decFtop();
		RegNum st0 = ibb->getFtop();
		RegNum sti = st0 - insn->rm;

		ibb->add( MOV( st0, sti, f64 ) );
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu
// fsqrt
void IA32Interpreter::fsqrt(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsqrt\n");
    //printf("fsqrt: 0x%08x\n", op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    ibb->add (FSQRTD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// fstl
void IA32Interpreter::fstl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fstl\n");
    //printf("fstl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (FST(t2, DOUBLE, t, mm_->map(0)));
}

// Added by zhengjuyu
// fsts
void IA32Interpreter::fsts(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsts\n");
    //printf("fsts: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (IA32LI(8, t3));
    ibb->add (FCONV(t2, DOUBLE, t3, FLOAT));
    //ibb->add (IA32LI(8, t3));
    ibb->add (FST(t3, WORD, t, mm_->map(0)));
}

// Added by zhengjuyu
// fstpl
void IA32Interpreter::fstpl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fstpl\n");
	XTRegNum t = resolveModRM(insn,op,bb);

	if(mode_ == NORMAL)
	{
		ibb->add (LD(0, (MemAddr)&top, t2, s32));
		ibb->add (FST(t2, DOUBLE, t, mm_->map(0)));
		//ibb->add (LD(0, (MemAddr)&top, WORD, t2));
		ibb->add (IA32LI(1, t3));
		ibb->add (IA32ADD(t2, t3, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (ST(t2, 0, (MemAddr)&top, s32));
	}
	else if(mode_ == PTX)
	{
		RegNum st0 = ibb->getFtop() - 1;
		ibb->add (FST(st0, DOUBLE, t, mm_->map(0)));
        ibb->decFtop();
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fistl\n");
    //printf("fistl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (IA32LI(8, t3));
    ibb->add (FCONV(t2, DOUBLE, t3, WORD));
    //ibb->add (IA32LI(8, t3));
    ibb->add (FST(t3, WORD, t, mm_->map(0)));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistpl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fistpl\n");
    //printf("fistpl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (FCONV(t2, DOUBLE, t2, WORD));
    //ibb->add (LD(0, (MemAddr)&top, WORD, t2));
    ibb->add (FST(t2, WORD, t, mm_->map(0)));

    //ibb->add (LD(0, (MemAddr)&top, WORD, t2));
    ibb->add (IA32LI(1, t3));
    ibb->add (IA32ADD(t2, t3, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (ST(t2, 0, (MemAddr)&top, s32));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistps(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fistps\n");
    //printf("fistps: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (FCONV(t2, DOUBLE, t2, WORD));

    //ibb->add (LD(0, (MemAddr)&top, WORD, t2));
    MemAddr offset = state_->fpget(1) - state_->fpget(0);
    ibb->add (IA32LI(offset, t3));
    ibb->add (IA32MULU(t2, t3, t4, t5));
    ibb->add (LD(t5, state_->fpget(0), t2, s16));
    ibb->add (ST(t2, t, 0, s16));

    //ibb->add (FST(t2, WORD, t, mm_->map(0)));

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (IA32LI(1, t3));
    ibb->add (IA32ADD(t2, t3, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (ST(t2, 0, (MemAddr)&top, s32));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistpll(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fistpll\n");
    //printf("fistpll: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (FCONV(t2, DOUBLE, t2, DWORD));

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    MemAddr offset = state_->fpget(1) - state_->fpget(0);
    ibb->add (IA32LI(offset, t3));
    ibb->add (IA32MULU(t2, t3, t4, t5));
    ibb->add (LD(t5, state_->fpget(0), t2, s32));
    ibb->add (ST(t2, t, 0, s32));
    ibb->add (LD(t5, state_->fpget(0) + 4, t2, s32));
    ibb->add (ST(t2, t, 4, s32));

    ibb->add (LD(0, (MemAddr)&top, t2, s32));
    ibb->add (IA32LI(1, t3));
    ibb->add (IA32ADD(t2, t3, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (ST(t2, 0, (MemAddr)&top, s32));
}

// Added by Chuchao
// d9 fstps
void IA32Interpreter::fstps(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fstps\n");
	XTRegNum t = resolveModRM(insn,op,bb);

	if(mode_ == NORMAL)
    {
        ibb->add (LD(0, (MemAddr)&top, t2, s32));
        ibb->add (IA32LI(8, t3));
        ibb->add (FCONV(t2, DOUBLE, t3, FLOAT));
        ibb->add (FST(t3, WORD, t, mm_->map(0)));

        ibb->add (IA32LI(1, t3));
        ibb->add (IA32ADD(t2, t3, t2));
        ibb->add (IA32LI(0x7, t3));
        ibb->add (IA32AND(t2, t3, t2));
        ibb->add (ST(t2, 0, (MemAddr)&top, s32));
    }
    else if(mode_ == PTX)
    {
		ibb->decFtop();
		RegNum st0 = ibb->getFtop();
		// fstps: copy ST(0) to m32fp
        ibb->add (FCONV(st0, DOUBLE, st0, FLOAT));
        ibb->add (FST(st0, WORD, t, 0));
    }
    else
    {
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
    }
}

// Added by Chuchao
// dd fldl
void IA32Interpreter::fldl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fldl\n");
	if(mode_ == NORMAL)
	{
		XTRegNum t = resolveModRM(insn, op, bb);

		ibb->add (LD(0, (MemAddr)&top, t2, s32));
		ibb->add (IA32LI(1, t3));
		ibb->add (IA32SUB(t2, t3, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (ST(t2, 0, (MemAddr)&top, s32));
		//ibb->add (LD(0, (MemAddr)&top, WORD, t2));
		ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
	}
	else if(mode_ == PTX)
	{
		XTRegNum t = resolveModRM(insn, op, bb);
		ibb->add (FLD(t, mm_->map(0), DOUBLE, ibb->getFtop()));
        ibb->incFtop();
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu 
// d9 C0 + i
// Push ST(i) onto the FPU register stack
void IA32Interpreter::fld_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fld_sti\n");

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (IA32LI(insn->rm, t2));
		ibb->add (IA32ADD(t2, t1, t2));
		ibb->add (IA32LI(0x7, t3));
		ibb->add (IA32AND(t2, t3, t2));
		ibb->add (FGETD(t2));

		//ibb->add (LD(0, (MemAddr)&top, WORD, t1));
		ibb->add (IA32LI(1, t2));
		ibb->add (IA32SUB(t1, t2, t1));
		ibb->add (IA32LI(0x7, t2));
		ibb->add (IA32AND(t1, t2, t1));
		ibb->add (ST(t1, 0, (MemAddr)&top, s32));
		ibb->add (FPUTD(t1));
	}
	else if( mode_ == PTX )
	{
		RegNum st0 = ibb->getFtop();
		RegNum sti = st0 - insn->rm - 1;
		//printf("st0 = %d, sti = %d\n", st0, sti);
		ibb->add( MOV( sti, st0, f64 ) );
		ibb->incFtop();
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by Chuchao
// d9 flds
void IA32Interpreter::flds(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("flds\n");

    //printf("address: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    if(mode_ == NORMAL)
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (LD(0, (MemAddr)&top, t2, s32));
        ibb->add (IA32LI(1, t3));
        ibb->add (IA32SUB(t2, t3, t2));
        ibb->add (IA32LI(0x7, t3));
        ibb->add (IA32AND(t2, t3, t2));
        ibb->add (ST(t2, 0, (MemAddr)&top, s32));

        ibb->add (FLD(t, mm_->map(0), WORD, t2));
        ibb->add (FCONV(t2, FLOAT, t2, DOUBLE));
    }
    else if(mode_ == PTX)
    {
        XTRegNum t = resolveModRM(insn,op,bb);

        ibb->add (FLD(t, 0, WORD, ibb->getFtop()));
        ibb->add (FCONV(ibb->getFtop(), FLOAT, ibb->getFtop(), DOUBLE));
        ibb->incFtop();
    }
    else
    {
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
    }
}

// Added by Chuchao
// d9 fldz
void IA32Interpreter::fldz(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fldz: 0x%08x\n", op->op3.imm);

	if(mode_ == NORMAL)
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (IA32LI(1, t2));
		ibb->add (IA32SUB(t1, t2, t1));
		ibb->add (IA32LI(0x7, t2));
		ibb->add (IA32AND(t1, t2, t1));
		ibb->add (ST(t1, 0, (MemAddr)&top, s32));

		MemAddr offset = state_->fpget(1) - state_->fpget(0);
		ibb->add (IA32LI(offset, t2));
		ibb->add (IA32MULU(t1, t2, t3, t4));

		ibb->add (ST(0, t4, state_->fpget(0), s32));
		ibb->add (ST(0, t4, state_->fpget(0) + 4, s32));
	}
	else if(mode_ == PTX)
	{
		ibb->add (GET(0, ibb->getFtop(), f64));
		ibb->incFtop();
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by Chuchao
// 
void IA32Interpreter::fld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fld1\n");
    //printf("top: %d\n", top);
    MemAddr offset = state_->fpget(1) - state_->fpget(0);
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32SUB(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
    ibb->add (IA32LI(offset, t2));
    ibb->add (IA32MULU(t1, t2, t3, t4));

    ibb->add (IA32LI(1, t1));
    ibb->add (ST(t1, t4, state_->fpget(0), s32));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FCONV(t1, WORD, t1, DOUBLE));
}

// Added by zhengjuyu
//
void IA32Interpreter::fxam(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fxam\n");
    //printf("fxam: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    ibb->add (FXAM());
    ibb->add (IA32LI(8, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
//
void IA32Interpreter::f2xm1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("f2xm1\n");
    //printf("f2xm1: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    ibb->add (F2XM1());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
//
void IA32Interpreter::fscale(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fscale\n");
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FSCALE());
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
    ibb->add (IA32LI(8, t2));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
//
void IA32Interpreter::fcos(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fcos\n");
	RegNum freg = ibb->getFtop() - 1;

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (FGETD(t1));
		ibb->add (FCOS(freg));
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (FPUTD(t1));
	}
	else if( mode_ == PTX )
	{
		ibb->add( FCOS(freg) );
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu
//
void IA32Interpreter::fsin(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fsin\n");
	RegNum freg = ibb->getFtop() - 1;

	if( mode_ == NORMAL )
	{
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (FGETD(t1));
		ibb->add (FSIN(freg));
		ibb->add (LD(0, (MemAddr)&top, t1, s32));
		ibb->add (FPUTD(t1));
	}
	else if( mode_ == PTX )
	{
		ibb->add (FSIN(freg));
	}
	else
	{
        UTIL::XTLOG("Unknown interp mode!\n");
        exit(0);
	}
}

// Added by zhengjuyu
//
void IA32Interpreter::fptan(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fptan\n");
	RegNum freg = ibb->getFtop() - 1;

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));
    ibb->add (FPTAN(freg));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32SUB(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
    ibb->add (FPUTD(t1));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// dd e9 fucom
void IA32Interpreter::fucom(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(ptx_msg) printf("fucom st(%d): 0x%08x\n", insn->rm, op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FCMPD(EQ, t1, t2, 9));
    ibb->add (FCMPD(BE, t1, t2, 10));

    ibb->add (LD(0, state_->fpget(9), t1, s32));
    ibb->add (IA32LI(14, t2));
    ibb->add (IA32SLL(t1, t2, t1));
    ibb->add (LD(0, state_->fpget(10), t2, s32));
    ibb->add (IA32LI(8, t3));
    ibb->add (IA32SLL(t2, t3, t2));
    ibb->add (IA32OR(t1, t2, t1));
    ibb->add (ST(t1, 0, state_->fpget(11), s32));
}

// Added by Chuchao
// dd e9 fucomp
void IA32Interpreter::fucomp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fucomp st(%d): 0x%08x\n", insn->rm, op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FCMPD(EQ, t1, t2, 9));
    ibb->add (FCMPD(BE, t1, t2, 10));

    ibb->add (LD(0, state_->fpget(9), t1, s32));
    ibb->add (IA32LI(14, t2));
    ibb->add (IA32SLL(t1, t2, t1));
    ibb->add (LD(0, state_->fpget(10), t2, s32));
    ibb->add (IA32LI(8, t3));
    ibb->add (IA32SLL(t2, t3, t2));
    ibb->add (IA32OR(t1, t2, t1));
    ibb->add (ST(t1, 0, state_->fpget(11), s32));
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
}

//
void IA32Interpreter::fcompl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fcompl: 0x%08x\n", op->op3.imm);

    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FCMPD(EQ, t1, t2, 9));
    ibb->add (FCMPD(BE, t1, t2, 10));

    ibb->add (LD(0, state_->fpget(9), t1, s32));
    ibb->add (IA32LI(14, t2));
    ibb->add (IA32SLL(t1, t2, t1));
    ibb->add (LD(0, state_->fpget(10), t2, s32));
    ibb->add (IA32LI(8, t3));
    ibb->add (IA32SLL(t2, t3, t2));
    ibb->add (IA32OR(t1, t2, t1));
    ibb->add (ST(t1, 0, state_->fpget(11), s32));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fucompp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fucompp st(%d): 0x%08x\n", insn->rm, op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    //ibb->add (IA32LI(9, t3));
    ibb->add (FCMPD(EQ, t1, t2, 9));
    //ibb->add (IA32LI(10, t3));
    ibb->add (FCMPD(BE, t1, t2, 10));
    //ibb->add (FCMPD(EQ, 6, 7, 9));
    //ibb->add (FCMPD(BE, 6, 7, 10));

    ibb->add (LD(0, state_->fpget(9), t1, s32));
    ibb->add (IA32LI(14, t2));
    ibb->add (IA32SLL(t1, t2, t1));
    ibb->add (LD(0, state_->fpget(10), t2, s32));
    ibb->add (IA32LI(8, t3));
    ibb->add (IA32SLL(t2, t3, t2));
    ibb->add (IA32OR(t1, t2, t1));
    ibb->add (ST(t1, 0, state_->fpget(11), s32));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(2, t2));
    ibb->add (IA32ADD(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fxch_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fxch st(%d): 0x%08x\n", insn->rm, op->op3.imm);
    //printf("top: %d\n", top);
    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FGETD(t2));

    ibb->add (IA32LI(8, t4));
    ibb->add (FPUTD(t4));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FGETD(t1));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));

    ibb->add (IA32LI(8, t4));
    ibb->add (FGETD(t4));

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (FPUTD(t1));
}

// Added by Chuchao
// df e0 fnstsw_ax
void IA32Interpreter::fnstsw_ax(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    ibb->add (LD(0, state_->fpget(11), TEMPREG1, s16));
    //op_size = HALFWORD;
    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
    ibb->add (IA32GET(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    ibb->add (IA32LI(0xffff0000, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

// Added by zhengjuyu
// DA
void IA32Interpreter::fidivl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fidivl: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    //ibb->add (IA32LI(8, t2));
    ibb->add (FCONV(t2, WORD, t2, DOUBLE));

    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (FDIVD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdiv_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdiv_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t1));
    ibb->add (FGETD(t2));
    ibb->add (FDIVD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdiv_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdiv_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FDIVD());

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (IA32LI(insn->rm, t2));
    //ibb->add (IA32ADD(t2, t1, t2));
    //ibb->add (IA32LI(0x7, t3));
    //ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdivp_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("top: %d\n", top);
    //printf("fdivp_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FDIVD());

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (IA32LI(insn->rm, t2));
    //ibb->add (IA32ADD(t2, t1, t2));
    //ibb->add (IA32LI(0x7, t3));
    //ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdivr_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivr_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t2));
    ibb->add (FGETD(t1));
    ibb->add (FDIVD());

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdivr_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivr_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t1));
    ibb->add (FGETD(t2));
    ibb->add (FDIVD());

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (IA32LI(insn->rm, t2));
    //ibb->add (IA32ADD(t2, t1, t2));
    //ibb->add (IA32LI(0x7, t3));
    //ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));
}

// Added by zhengjuyu
void IA32Interpreter::fdivrs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivrs: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, FLOAT, t2, DOUBLE));

    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (FDIVD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
void IA32Interpreter::fdivs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivs: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, FLOAT, t2, DOUBLE));

    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (FDIVD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// DA
void IA32Interpreter::fidivrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fidirvl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), WORD, t2));
    ibb->add (FCONV(t2, WORD, t2, DOUBLE));
    ibb->add (IA32LI(8, t2));
    ibb->add (FGETD(t2));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (FDIVD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// DA
void IA32Interpreter::fdivrp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivrp st(i): 0x%08x\n", insn->rm, op->op3.imm);

    ibb->add (LD(0, (MemAddr)&top, t1, s32));
    ibb->add (IA32LI(insn->rm, t2));
    ibb->add (IA32ADD(t2, t1, t2));
    ibb->add (IA32LI(0x7, t3));
    ibb->add (IA32AND(t2, t3, t2));

    ibb->add (FGETD(t1));
    ibb->add (FGETD(t2));
    ibb->add (FDIVD());

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    //ibb->add (IA32LI(insn->rm, t2));
    //ibb->add (IA32ADD(t2, t1, t2));
    //ibb->add (IA32LI(0x7, t3));
    //ibb->add (IA32AND(t2, t3, t2));
    ibb->add (FPUTD(t2));

    //ibb->add (LD(0, (MemAddr)&top, WORD, t1));
    ibb->add (IA32LI(1, t2));
    ibb->add (IA32ADD(t1, t2, t1));
    ibb->add (IA32LI(0x7, t2));
    ibb->add (IA32AND(t1, t2, t1));
    ibb->add (ST(t1, 0, (MemAddr)&top, s32));
}

// Added by zhengjuyu
// DC
void IA32Interpreter::fdivrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivrl 0x%08x\n", op->op3.imm);

    XTRegNum t = resolveModRM(insn,op,bb);
    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    ibb->add (FGETD(t2));
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (FDIVD());
    //ibb->add (LD(0, (MemAddr)&top, WORD, t3));
    ibb->add (FPUTD(t3));
}

// Added by zhengjuyu
// DC
void IA32Interpreter::fdivl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //no verify
    //printf("fdivl 0x%08x\n", op->op3.imm);

    XTRegNum t = resolveModRM(insn,op,bb);
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FGETD(t3));
    ibb->add (IA32LI(8, t2));
    ibb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    ibb->add (FGETD(t2));
    ibb->add (FDIVD());
    ibb->add (LD(0, (MemAddr)&top, t3, s32));
    ibb->add (FPUTD(t3));
}

//25 Ia_andw_AX_Iw
void IA32Interpreter::AX_i_andw25(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI (op->op2.imm, TEMPREG1));
    ibb->add (IA32AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
    ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

    ibb->add (IA32LI(0xffff0000, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//0D Ia_orw_AX_Iw
void IA32Interpreter::AX_i_orw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI (op->op2.imm, TEMPREG1));
    ibb->add (IA32OR(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    ibb->add (ZEXT(TEMPREG1, TEMPREG1, b16));
    ibb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

    ibb->add (IA32LI(0xffff0000, TEMPREG2));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//25 Ia_andl_EAX_Id
void IA32Interpreter::EAX_i_andl25(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    ibb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32LI (op->op2.imm, TEMPREG1));
    ibb->add (IA32AND(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    ibb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    //ibb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(IA32ProcessorState::EAX)));
	SET_FLAGS_ANDL( VREG(IA32ProcessorState::EAX) )
}

//XXX
//0F AC Ia_shrdl_Ed_Gd_Id
void IA32Interpreter::rorm_r_i_shrdl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    /*
       ibb->add (IA32LI (op->op3.imm,t1));
       ibb->add (IA32LI (32, t2));
       ibb->add (IA32SUB(t2,t1,t2));
       ibb->add (IA32GET(op->op2.reg,t3));
       ibb->add (IA32SLL(t3,t2,t4));

       XTRegNum t = resolveModRM(insn, op, bb);

       if (insn->mod == 3)
       {
       ibb->add (IA32GET(insn->rm,t2));
       ibb->add (IA32LI (op->op3.imm,t3));
       ibb->add (IA32SRL(t2,t3,t5));
       ibb->add (IA32OR (t5,t4,t5));
       ibb->add (IA32PUT(t5,insn->rm));
       }
       else
       {
       ibb->add (LD(t, mm_->map(0), WORD, t2));	// M[t2] = t1
       ibb->add (IA32LI (op->op3.imm,t3));
       ibb->add (IA32SRL(t2,t3,t5));
       ibb->add (IA32OR (t5,t4,t5));
       ibb->add (ST(t5, WORD, t, mm_->map(0)));	// M[t2] = t1
       }
       ibb->add (IA32LI ((Word)state_, t4));
       ibb->add (CALL((Word)(&crossbit::set_flags_shrdl),4,t4,t2,t5,t3));
       */
    // printf("shrd\n");
    if (insn->mod == 3)
    {
        int shift = ((op->op3.imm) & 0x1f);
        int left = 32 - shift;

        ibb->add (IA32LI(left, TEMPREG1));
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32SLL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));

        ibb->add (IA32LI(shift, TEMPREG3));
        ibb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
        ibb->add (IA32MOV(VREG(op->op1.reg), TEMPREG1));
        ibb->add (IA32SRL(VREG(op->op1.reg), TEMPREG3, VREG(op->op1.reg)));
        ibb->add (IA32OR (VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
        ibb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
        ibb->add (CALL((Word)(&crossbit::set_flags_shrdl1),3, TEMPREG1, VREG(op->op1.reg), TEMPREG3));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);

        int shift = ((op->op3.imm) & 0x1f);
        int left = 32 - shift;

        ibb->add (IA32LI(left, TEMPREG1));
        ibb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
        ibb->add (IA32SLL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));

        ibb->add (IA32LI(shift, TEMPREG4));
        ibb->add (LD(t, mm_->map(0), TEMPREG1, s32));	// M[t2] = t1
        ibb->add (IA32SRL(TEMPREG1, TEMPREG4, TEMPREG3));
        ibb->add (IA32OR (TEMPREG3, TEMPREG2, TEMPREG3));
        ibb->add (ST (TEMPREG3, t, 0, s32));	// M[t2] = t1

        ibb->add (CALL((Word)(&crossbit::set_flags_shrdl1), 3, TEMPREG1, TEMPREG3, TEMPREG4));
    }
}

XTMemAddr IA32Interpreter::decode (XTMemAddr pc, VBlockBuilder *bb)
{
    MemAddr next = pc;	      // initialize next pc address
    // MemAddr at = mm_->map(pc); // locate the code address in memory image
    MemAddr at = pc; // locate the code address in memory image

    disassembler disasm;
    disasm.set_syntax_intel();

    struct x86_operand op;
    XbitCallbackPtr_t cb;

    struct x86_insn insn(1, 0);

    curNext = next;

    segOver = false;
    op_size = WORD;
    dtype = s32;

    //modified
    insn = disasm.decode(1, 0, (bx_address)0, (bx_address)next, (Bit8u*)at, &cb, &op);

    if( cb != NULL ) {
        if (insn.prefixes)
        {
            Byte prefix_byte = *((Byte*)mm_->map(pc));

            switch(prefix_byte)
            {
                case 0xF0:	// LOCK
                    {
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0xF2:	// REPNZ
                    {
                        hasRep = true;
                        repFlag = 1;
                        next += 1;
                        break;
                    }

                case 0xF3:	// REP
                    {
                        hasRep = true;
                        repFlag = 2;
                        next += 1;
                        break;
                    }
                case 0x65:
                    {
                        segOver = true;
                        segReg = IA32ProcessorState::GS;
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0x66:
                    {
                        //op_size = HALFWORD;
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0x3E:
                    {
                        // SEG = DS
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0x2E:
                    {
                        // SEG = CS
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
            }
        }
        else
        {
            (this->*cb)(&insn, &op, bb);
            next += insn.ilen; 
        }
    }
    else {
        printf("Unimplemented callback!\n");
        printf("The source addr is 0x%x!\n", (Word)next);
        printf("The opcode is 0x%2x,prefix%2d,mod %2x!\n", (Byte)insn.b1,insn.prefixes,insn.modrm);
        exit(-1);
    }

    return next;
}

XTMemAddr IA32Interpreter::decode (XTMemAddr pc, VBlockBuilder *bb, bool &status)
{
    MemAddr next = pc;	      // initialize next pc address
    // MemAddr at = mm_->map(pc); // locate the code address in memory image
    MemAddr at = pc; // locate the code address in memory image

    disassembler disasm;
    disasm.set_syntax_intel();

    struct x86_operand op;
    XbitCallbackPtr_t cb;

    struct x86_insn insn(1, 0);

    curNext = next;

    segOver = false;
    op_size = WORD;
    dtype = s32;

    //modified
    insn = disasm.decode(1, 0, (bx_address)0, (bx_address)next, (Bit8u*)at, &cb, &op);

    if( cb != NULL ) {
        if (insn.prefixes)
        {
            Byte prefix_byte = *((Byte*)mm_->map(pc));

            switch(prefix_byte)
            {
                case 0xF0:	// LOCK
                    {
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0xF2:	// REPNZ
                    {
                        hasRep = true;
                        repFlag = 1;
                        next += 1;
                        break;
                    }

                case 0xF3:	// REP
                    {
                        hasRep = true;
                        repFlag = 2;
                        next += 1;
                        break;
                    }
                case 0x65:
                    {
                        segOver = true;
                        segReg = IA32ProcessorState::GS;
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0x66:
                    {
                        //op_size = HALFWORD;
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0x3E:
                    {
                        // SEG = DS
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
                case 0x2E:
                    {
                        // SEG = CS
                        (this->*cb)(&insn, &op, bb);
                        next += insn.ilen; 
                        break;
                    }
            }
        }
        else
        {
            (this->*cb)(&insn, &op, bb);
            next += insn.ilen; 
        }
    }
    else {
		status = false;
		next += insn.ilen;
    }

    return next;
}
